Repository: Eve-ning/glcm-cupy (language: python)

Issue:
Combine GLCM class to glcm and GLCM.run variants



Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 646b494..20d7292 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ These are the features implemented.
 - `MEAN = 3`
 - `VAR = 4`
 - `CORRELATION = 5`
+- `DISSIMILARITY = 6`
 
 Don't see one you need? Raise an issue, I'll (hopefully) add it.
 
diff --git a/docs/_sources/batch_processing.rst.txt b/docs/_sources/batch_processing.rst.txt
index 6351fc5..bfb5628 100644
--- a/docs/_sources/batch_processing.rst.txt
+++ b/docs/_sources/batch_processing.rst.txt
@@ -20,7 +20,7 @@ This is slightly faster on ``GLCM``, it will start on the next image while the c
     >>> # This is why you need them to be the same size
     >>> g = GLCM(np.stack([ar0, ar1])).run(ar)
     >>> g.shape
-    (2, 1074, 1914, 3, 6)
+    (2, 1074, 1914, 3, 7)
     >>> g0, g1 = g[0], g[1]
 
 The dimensions here are ``(batch, height, width, channel, features)``.
@@ -36,7 +36,7 @@ GLCMCross
 
     >>> g = GLCMCross(np.stack([ar0, ar1])).run(ar)
     >>> g.shape
-    (2, 1074, 1914, 3, 6)
+    (2, 1074, 1914, 3, 7)
     >>> g0, g1 = g[0], g[1]
 
 Behavior of the ``ix_combos`` specified does not change.
diff --git a/docs/_sources/changelog.rst.txt b/docs/_sources/changelog.rst.txt
index a909f34..f8532c1 100644
--- a/docs/_sources/changelog.rst.txt
+++ b/docs/_sources/changelog.rst.txt
@@ -33,4 +33,6 @@ Changelog
 - Implemented GLCM Feature Selection to optimize out unnecessary GLCM Stages
 - Fix issue with CuPy ndarray incompatible with tqdm
 - Add Batch Processing for vanilla GLCM
-    - ``GLCMCross`` doesn't perform faster with this. However is compatible.
\ No newline at end of file
+    - ``GLCMCross`` doesn't perform faster with this. However is compatible.
+- Implement Dissimilarity Feature
+
diff --git a/docs/_sources/features.rst.txt b/docs/_sources/features.rst.txt
index afb8aad..e9a17e4 100644
--- a/docs/_sources/features.rst.txt
+++ b/docs/_sources/features.rst.txt
@@ -44,7 +44,8 @@ In total, we have 6 features.
     \text{Angular Second Moment (ASM)} = \sum_{i,j=0}^{N-1}P_{i,j}^2\\
     \text{GLCM Mean, } \mu = \sum_{i,j=0}^{N-1}i * P_{i,j}\\
     \text{GLCM Variance, } \sigma^2 = \sum_{i,j=0}^{N-1}P_{i,j}(i - \mu_i)^2\\
-    \text{Correlation} = \frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+    \text{Correlation} = \sum_{i,j=0}^{N-1}P_{i,j}\frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+    \text{Dissimilarity} = \sum_{i,j=0}^{N-1}P_{i,j} * \left\lvert i - j \right\rvert\\
 
 We implemented these few as they are the most orthogonal (according to the tutorial).
 However, feel free to suggest any more in the GitHub Issue page.
diff --git a/docs/batch_processing.html b/docs/batch_processing.html
index 288158a..0560bdb 100644
--- a/docs/batch_processing.html
+++ b/docs/batch_processing.html
@@ -173,7 +173,7 @@ <h1>Batch Processing<a class="headerlink" href="#batch-processing" title="Permal
 <span class="gp">&gt;&gt;&gt; </span><span class="c1"># This is why you need them to be the same size</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g</span> <span class="o">=</span> <span class="n">GLCM</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">([</span><span class="n">ar0</span><span class="p">,</span> <span class="n">ar1</span><span class="p">]))</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">ar</span><span class="p">)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g</span><span class="o">.</span><span class="n">shape</span>
-<span class="go">(2, 1074, 1914, 3, 6)</span>
+<span class="go">(2, 1074, 1914, 3, 7)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g0</span><span class="p">,</span> <span class="n">g1</span> <span class="o">=</span> <span class="n">g</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">g</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
 </pre></div>
 </div>
@@ -184,7 +184,7 @@ <h2>GLCMCross<a class="headerlink" href="#glcmcross" title="Permalink to this he
 <p><code class="docutils literal notranslate"><span class="pre">GLCMCross</span></code> does not benefit in speed, however it may be simpler in syntax.</p>
 <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">g</span> <span class="o">=</span> <span class="n">GLCMCross</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">([</span><span class="n">ar0</span><span class="p">,</span> <span class="n">ar1</span><span class="p">]))</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">ar</span><span class="p">)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g</span><span class="o">.</span><span class="n">shape</span>
-<span class="go">(2, 1074, 1914, 3, 6)</span>
+<span class="go">(2, 1074, 1914, 3, 7)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g0</span><span class="p">,</span> <span class="n">g1</span> <span class="o">=</span> <span class="n">g</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">g</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
 </pre></div>
 </div>
diff --git a/docs/changelog.html b/docs/changelog.html
index 5cfae64..501b5d5 100644
--- a/docs/changelog.html
+++ b/docs/changelog.html
@@ -223,6 +223,7 @@ <h2>1.10<a class="headerlink" href="#id8" title="Permalink to this headline">¶<
 </dd>
 </dl>
 </li>
+<li><p>Implement Dissimilarity Feature</p></li>
 </ul>
 </div>
 </div>
diff --git a/docs/features.html b/docs/features.html
index 3747b23..ed1c577 100644
--- a/docs/features.html
+++ b/docs/features.html
@@ -95,6 +95,7 @@
 <li class="toctree-l1"><a class="reference internal" href="binning.html">Binning</a></li>
 <li class="toctree-l1"><a class="reference internal" href="direction.html">Direction</a></li>
 <li class="toctree-l1"><a class="reference internal" href="radius_step_size.html">Radius &amp; Step Size</a></li>
+<li class="toctree-l1"><a class="reference internal" href="batch_processing.html">Batch Processing</a></li>
 <li class="toctree-l1"><a class="reference internal" href="acknowledgements.html">Acknowledgements</a></li>
 <li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog</a></li>
 </ul>
@@ -194,7 +195,8 @@ <h2>Feature Theory<a class="headerlink" href="#feature-theory" title="Permalink
 \text{Angular Second Moment (ASM)} = \sum_{i,j=0}^{N-1}P_{i,j}^2\\
 \text{GLCM Mean, } \mu = \sum_{i,j=0}^{N-1}i * P_{i,j}\\
 \text{GLCM Variance, } \sigma^2 = \sum_{i,j=0}^{N-1}P_{i,j}(i - \mu_i)^2\\
-\text{Correlation} = \frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\\end{split}\]</div>
+\text{Correlation} = \sum_{i,j=0}^{N-1}P_{i,j}\frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+\text{Dissimilarity} = \sum_{i,j=0}^{N-1}P_{i,j} * \left\lvert i - j \right\rvert\\\end{split}\]</div>
 <p>We implemented these few as they are the most orthogonal (according to the tutorial).
 However, feel free to suggest any more in the GitHub Issue page.</p>
 </div>
diff --git a/docs/searchindex.js b/docs/searchindex.js
index 08e16a8..4b53d09 100644
--- a/docs/searchindex.js
+++ b/docs/searchindex.js
@@ -1,1 +1,1 @@
-Search.setIndex({docnames:["acknowledgements","batch_processing","binning","changelog","direction","features","glcm_cross","index","radius_step_size"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["acknowledgements.rst","batch_processing.rst","binning.rst","changelog.rst","direction.rst","features.rst","glcm_cross.rst","index.rst","radius_step_size.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,5,6,8],"1":[1,5,6,7,8],"10":7,"1074":[1,7],"1080":[1,6,7],"11":[3,7],"13":3,"15":2,"16":2,"18":3,"1914":[1,7],"1920":[1,6,7],"1st":1,"2":[1,2,5,6],"25":3,"255":2,"256":2,"3":[1,6,7,8],"3rd":6,"4":[2,4],"5":5,"6":[1,5,6,7],"7":7,"8":7,"9":7,"default":7,"do":0,"function":8,"import":[1,2,4,5,6,7,8],"int":8,"return":5,"try":2,"while":1,As:2,By:6,For:7,If:[1,8],In:[5,6],It:[1,7,8],On:4,That:4,The:[1,2,4,6,8],Then:7,To:[2,5,6,7],_:7,__:7,about:7,accord:5,achiev:4,acknowledg:7,ad:4,add:3,after:[0,6],ahead:8,ai:[],algorithm:4,all:[1,6],alwai:3,an:[2,6,7],angular:5,ani:[5,8],ar0:[1,7],ar1:[1,7],ar2:7,ar:[1,2,3,4,5,6,7,8],arg:7,argument:2,articl:7,asarrai:[2,4,6,8],asm:5,automat:7,avail:4,bar:7,batch:[3,7],behavior:1,being:1,benefit:1,benjamin:0,between:[6,8],bi:7,bin:[0,7],bin_from:2,bin_to:2,blank:1,c:7,can:[4,5,6],caution:7,caveat:6,center:8,chang:1,changelog:7,channel:[1,5,6],check:[3,7],com:[],combin:[1,7],compat:3,complex:2,concurr:1,conda:7,consid:[6,7],contrast:[5,6,7,8],correl:[5,7,8],cost:4,cover:4,cross:[3,7],cucim:[3,7],cuda:7,cudatoolkit:7,cupi:3,current:1,cv2:[1,5,7],def:8,defin:8,depend:[3,7],determin:5,diagon:8,diamet:8,dimens:[1,6,7],direct:[2,7],direction:7,distanc:8,doe:[1,5],doesn:3,dr:0,drastic:2,drop:3,e:2,each:[1,6,8],east:4,enabl:7,euclidean:8,ev:[],extend:0,fail:8,faster:[1,3],featur:[1,3,6,7],feel:5,few:5,first:7,fix:3,float32:3,follow:[0,5,6],forg:7,frac:5,free:5,from:[1,2,4,5,6,7,8],g0:[1,7],g1:[1,7],g2:7,g:[1,2,4,5,6,7,8],gap:[4,5],gener:[1,6,7],get:7,github:5,glcm:[1,2,3,4,8],glcm_cross:6,glcm_cupi:[1,2,4,5,6,7,8],glcm_shape:8,glcmcross:[3,6,7],goh:0,gratitud:0,guid:7,ha:8,have:[1,5,7,8],height:1,helper:8,here:[1,4,5],hi:0,higher:2,homogen:5,host:0,howev:[1,3,5,6],html:[],http:[],i:[0,3,4,5,6,7],idea:0,im_shap:8,imag:[1,2,4,5,6,7,8],image_0:1,image_1:1,implement:[0,3,5],imread:[1,5,7],includ:[2,8],incompat:3,increas:2,index:7,indic:6,indirectli:6,input:[2,3],instal:[],instanc:6,integr:3,issu:[3,5],itertool:6,ix_combo:[1,6],j:[3,4,5,6],ji:0,jifei:0,jon:0,jpg:[1,2,4,5,6,7,8],kernel:4,know:8,knowledg:[4,5],last:[6,7],learn:7,left:7,like:[6,7],limit:2,ll:[1,4,8],loop:1,mai:[1,4,6,8],make:3,mani:7,manual:7,max:2,maximum:2,me:[0,7],mean:[4,5],merg:3,moment:5,more:5,most:5,mu:5,mu_i:5,mu_j:5,multipl:1,my:0,n:[2,5],ndarrai:3,need:[0,1,2,7],neglig:4,next:1,ning:[],none:6,normal:5,note:[1,5],np:[1,2,4,6,7,8],numba:0,numpi:[2,4,6,8],o:2,onc:7,onli:6,open:[2,4,6,8],opt:1,optim:3,option:3,order:[5,6],orthogon:5,other:[4,5],out:3,output:3,overflow:3,p_:5,page:5,pars:5,peopl:0,perform:[3,4],pil:[2,4,6,8],pip:7,pixel:8,popul:6,possibl:6,pr:3,print:5,process:[3,7],project:0,properti:6,provid:0,purpos:2,push:0,python:7,radiu:7,rang:6,rapid:[3,7],re:6,readi:2,recommend:[4,5,7],reduc:[2,5],referenc:[4,5],reflect:4,reject:8,relationship:6,replac:7,requir:2,resolv:3,result:8,retriev:[1,5,7],reus:[6,7],run:[1,2,4,5,6,7,8],s:[1,2,4,5,7,8],same:[1,3,7],scale:7,second:5,select:[3,7],separ:6,shape:[1,6,7,8],shape_aft:8,shrink:2,side:7,sigma:5,sigma_i:5,sigma_j:5,signatur:8,simpler:1,simpli:4,sit:0,size:[1,2,7],skip:6,slightli:1,small:8,so:[1,6,7],south:4,south_east:4,south_west:4,specif:5,specifi:[1,4,6],speed:1,spur:0,sqrt:5,stabil:3,stack:[1,7],stage:3,start:1,statist:6,step:7,step_siz:8,still:1,suggest:5,suitabl:7,sum_:5,support:[3,7],syntax:[1,5],t:[3,6],taken:[2,6],test:[2,3],text:5,than:1,thei:5,them:[1,4],theori:7,thi:[0,1,3,4,5,7,8],thu:[2,4,6],time:[5,7,8],too:8,top:4,total:5,tqdm:3,treat:8,tupl:8,tutori:[4,5],unnecessari:3,us:[2,4,5,6,7],valu:[2,8],vanilla:3,variabl:3,varianc:5,version:7,view:7,wang:0,we:[2,4,5,7,8],west:4,when:[2,6],why:1,width:1,window:8,work:7,yield:6,you:[1,4,5,6,7,8],zero:5},titles:["Acknowledgements","Batch Processing","Binning","Changelog","Direction","GLCM Feature Indexing","Cross GLCM","GLCM Implemented in CuPy","Radius &amp; Step Size"],titleterms:{"1":3,"10":3,"6":3,"7":3,"8":3,"9":3,"default":6,acknowledg:0,batch:1,bi:4,bin:2,caution:2,changelog:3,check:8,combin:6,content:7,cross:6,cupi:7,direct:4,direction:4,featur:5,get:5,glcm:[5,6,7],glcmcross:1,implement:7,index:5,instal:7,more:7,option:7,process:1,quick:7,radiu:8,read:7,recommend:2,retriev:6,scale:2,select:[5,6],size:8,start:7,step:8,suitabl:8,theori:5,time:2,usag:[6,7]}})
\ No newline at end of file
+Search.setIndex({docnames:["acknowledgements","batch_processing","binning","changelog","direction","features","glcm_cross","index","radius_step_size"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["acknowledgements.rst","batch_processing.rst","binning.rst","changelog.rst","direction.rst","features.rst","glcm_cross.rst","index.rst","radius_step_size.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,5,6,8],"1":[1,5,6,7,8],"10":7,"1074":[1,7],"1080":[1,6,7],"11":[3,7],"13":3,"15":2,"16":2,"18":3,"1914":[1,7],"1920":[1,6,7],"1st":1,"2":[1,2,5,6],"25":3,"255":2,"256":2,"3":[1,6,7,8],"3rd":6,"4":[2,4],"5":5,"6":[5,6,7],"7":[1,7],"8":7,"9":7,"default":7,"do":0,"function":8,"import":[1,2,4,5,6,7,8],"int":8,"return":5,"try":2,"while":1,As:2,By:6,For:7,If:[1,8],In:[5,6],It:[1,7,8],On:4,That:4,The:[1,2,4,6,8],Then:7,To:[2,5,6,7],_:7,__:7,about:7,accord:5,achiev:4,acknowledg:7,ad:4,add:3,after:[0,6],ahead:8,ai:[],algorithm:4,all:[1,6],alwai:3,an:[2,6,7],angular:5,ani:[5,8],ar0:[1,7],ar1:[1,7],ar2:7,ar:[1,2,3,4,5,6,7,8],arg:7,argument:2,articl:7,asarrai:[2,4,6,8],asm:5,automat:7,avail:4,bar:7,batch:[3,7],behavior:1,being:1,benefit:1,benjamin:0,between:[6,8],bi:7,bin:[0,7],bin_from:2,bin_to:2,blank:1,c:7,can:[4,5,6],caution:7,caveat:6,center:8,chang:1,changelog:7,channel:[1,5,6],check:[3,7],com:[],combin:[1,7],compat:3,complex:2,concurr:1,conda:7,consid:[6,7],contrast:[5,6,7,8],correl:[5,7,8],cost:4,cover:4,cross:[3,7],cucim:[3,7],cuda:7,cudatoolkit:7,cupi:3,current:1,cv2:[1,5,7],def:8,defin:8,depend:[3,7],determin:5,diagon:8,diamet:8,dimens:[1,6,7],direct:[2,7],direction:7,dissimilar:[3,5],distanc:8,doe:[1,5],doesn:3,dr:0,drastic:2,drop:3,e:2,each:[1,6,8],east:4,enabl:7,euclidean:8,ev:[],extend:0,fail:8,faster:[1,3],featur:[1,3,6,7],feel:5,few:5,first:7,fix:3,float32:3,follow:[0,5,6],forg:7,frac:5,free:5,from:[1,2,4,5,6,7,8],g0:[1,7],g1:[1,7],g2:7,g:[1,2,4,5,6,7,8],gap:[4,5],gener:[1,6,7],get:7,github:5,glcm:[1,2,3,4,8],glcm_cross:6,glcm_cupi:[1,2,4,5,6,7,8],glcm_shape:8,glcmcross:[3,6,7],goh:0,gratitud:0,guid:7,ha:8,have:[1,5,7,8],height:1,helper:8,here:[1,4,5],hi:0,higher:2,homogen:5,host:0,howev:[1,3,5,6],html:[],http:[],i:[0,3,4,5,6,7],idea:0,im_shap:8,imag:[1,2,4,5,6,7,8],image_0:1,image_1:1,implement:[0,3,5],imread:[1,5,7],includ:[2,8],incompat:3,increas:2,index:7,indic:6,indirectli:6,input:[2,3],instal:[],instanc:6,integr:3,issu:[3,5],itertool:6,ix_combo:[1,6],j:[3,4,5,6],ji:0,jifei:0,jon:0,jpg:[1,2,4,5,6,7,8],kernel:4,know:8,knowledg:[4,5],last:[6,7],learn:7,left:[5,7],like:[6,7],limit:2,ll:[1,4,8],loop:1,lvert:5,mai:[1,4,6,8],make:3,mani:7,manual:7,max:2,maximum:2,me:[0,7],mean:[4,5],merg:3,moment:5,more:5,most:5,mu:5,mu_i:5,mu_j:5,multipl:1,my:0,n:[2,5],ndarrai:3,need:[0,1,2,7],neglig:4,next:1,ning:[],none:6,normal:5,note:[1,5],np:[1,2,4,6,7,8],numba:0,numpi:[2,4,6,8],o:2,onc:7,onli:6,open:[2,4,6,8],opt:1,optim:3,option:3,order:[5,6],orthogon:5,other:[4,5],out:3,output:3,overflow:3,p_:5,page:5,pars:5,peopl:0,perform:[3,4],pil:[2,4,6,8],pip:7,pixel:8,popul:6,possibl:6,pr:3,print:5,process:[3,7],project:0,properti:6,provid:0,purpos:2,push:0,python:7,radiu:7,rang:6,rapid:[3,7],re:6,readi:2,recommend:[4,5,7],reduc:[2,5],referenc:[4,5],reflect:4,reject:8,relationship:6,replac:7,requir:2,resolv:3,result:8,retriev:[1,5,7],reus:[6,7],right:5,run:[1,2,4,5,6,7,8],rvert:5,s:[1,2,4,5,7,8],same:[1,3,7],scale:7,second:5,select:[3,7],separ:6,shape:[1,6,7,8],shape_aft:8,shrink:2,side:7,sigma:5,sigma_i:5,sigma_j:5,signatur:8,simpler:1,simpli:4,sit:0,size:[1,2,7],skip:6,slightli:1,small:8,so:[1,6,7],south:4,south_east:4,south_west:4,specif:5,specifi:[1,4,6],speed:1,spur:0,sqrt:5,stabil:3,stack:[1,7],stage:3,start:1,statist:6,step:7,step_siz:8,still:1,suggest:5,suitabl:7,sum_:5,support:[3,7],syntax:[1,5],t:[3,6],taken:[2,6],test:[2,3],text:5,than:1,thei:5,them:[1,4],theori:7,thi:[0,1,3,4,5,7,8],thu:[2,4,6],time:[5,7,8],too:8,top:4,total:5,tqdm:3,treat:8,tupl:8,tutori:[4,5],unnecessari:3,us:[2,4,5,6,7],valu:[2,8],vanilla:3,variabl:3,varianc:5,version:7,view:7,wang:0,we:[2,4,5,7,8],west:4,when:[2,6],why:1,width:1,window:8,work:7,yield:6,you:[1,4,5,6,7,8],zero:5},titles:["Acknowledgements","Batch Processing","Binning","Changelog","Direction","GLCM Feature Indexing","Cross GLCM","GLCM Implemented in CuPy","Radius &amp; Step Size"],titleterms:{"1":3,"10":3,"6":3,"7":3,"8":3,"9":3,"default":6,acknowledg:0,batch:1,bi:4,bin:2,caution:2,changelog:3,check:8,combin:6,content:7,cross:6,cupi:7,direct:4,direction:4,featur:5,get:5,glcm:[5,6,7],glcmcross:1,implement:7,index:5,instal:7,more:7,option:7,process:1,quick:7,radiu:8,read:7,recommend:2,retriev:6,scale:2,select:[5,6],size:8,start:7,step:8,suitabl:8,theori:5,time:2,usag:[6,7]}})
\ No newline at end of file
diff --git a/examples/process_an_image/main.py b/examples/process_an_image/main.py
index 0119e9c..d2530aa 100644
--- a/examples/process_an_image/main.py
+++ b/examples/process_an_image/main.py
@@ -1,13 +1,9 @@
 """ Example Code """
-#%%
-import numpy as np
-from PIL import Image
-
-
 # Here, we load in the array
 # We divide the image by / 16 as it'll take too long
+from matplotlib.image import imread
 
-ar = np.asarray(Image.open("../../data/image.jpg"))[::4,::4]
+ar = imread("../../data/image.jpg")[::4, ::4]
 
 #%%
 # We may use the class variant to run GLCM
@@ -25,12 +21,12 @@
 
 #%%
 # We yield the features using constants defined in conf
-from glcm_cupy.conf import CONTRAST, CORRELATION, ASM
+from glcm_cupy.conf import Features
 
-print(g[..., CONTRAST])
-print(g[..., CORRELATION])
-print(g[..., ASM])
-#%%
+print(g[..., Features.CONTRAST])
+print(g[..., Features.CORRELATION])
+print(g[..., Features.ASM])
+# %%
 # Alternatively, since these constants are simply integers
 print(g[..., 0])
 print(g[..., 1])
diff --git a/glcm_cupy/__init__.py b/glcm_cupy/__init__.py
index dbea49e..919bbc7 100644
--- a/glcm_cupy/__init__.py
+++ b/glcm_cupy/__init__.py
@@ -1,4 +1,4 @@
-from glcm_cupy.conf import HOMOGENEITY, CONTRAST, ASM, MEAN, VARIANCE, CORRELATION
+from glcm_cupy.conf import Features
 from glcm_cupy.glcm import glcm, GLCM, Direction
 from glcm_cupy.cross import glcm_cross, GLCMCross
 
@@ -7,11 +7,6 @@
     "glcm_cross",
     "GLCM",
     "GLCMCross",
-    "HOMOGENEITY",
-    "CONTRAST",
-    "ASM",
-    "MEAN",
-    "VARIANCE",
-    "CORRELATION",
+    "Features",
     "Direction",
 ]
diff --git a/glcm_cupy/conf.py b/glcm_cupy/conf.py
index c612667..d2d2a92 100644
--- a/glcm_cupy/conf.py
+++ b/glcm_cupy/conf.py
@@ -1,3 +1,4 @@
+from enum import IntEnum
 from pathlib import Path
 from typing import Union
 
@@ -15,13 +16,17 @@
 # Each cell is 4 bytes (float32)
 MAX_PARTITION_SIZE = 1000
 
-NO_OF_FEATURES = 6
 
-HOMOGENEITY = 0
-CONTRAST = 1
-ASM = 2
-MEAN = 3
-VARIANCE = 4
-CORRELATION = 5
+class Features(IntEnum):
+    HOMOGENEITY = 0
+    CONTRAST = 1
+    ASM = 2
+    MEAN = 3
+    VARIANCE = 4
+    CORRELATION = 5
+    DISSIMILARITY = 6
+
+
+NO_OF_FEATURES = len(Features)
 
 ndarray = Union[np.ndarray, cp.ndarray]
diff --git a/glcm_cupy/cross/glcm_cross.py b/glcm_cupy/cross/glcm_cross.py
index 19015f6..dc9c72c 100644
--- a/glcm_cupy/cross/glcm_cross.py
+++ b/glcm_cupy/cross/glcm_cross.py
@@ -26,8 +26,14 @@ def glcm_cross(
     max_partition_size: int = MAX_PARTITION_SIZE,
     max_threads: int = MAX_THREADS,
     normalized_features: bool = True,
-    features: Set[int] = (HOMOGENEITY, CONTRAST, ASM,
-                          MEAN, VARIANCE, CORRELATION),
+    features: Set[int] = (Features.HOMOGENEITY,
+                          Features.CONTRAST,
+                          Features.ASM,
+                          Features.MEAN,
+                          Features.VARIANCE,
+                          Features.CORRELATION,
+                          Features.DISSIMILARITY,
+                          ),
     verbose: bool = True,
     ix_combos: List[Tuple[int, int]] | None = None
 ) -> ndarray:
diff --git a/glcm_cupy/glcm/glcm.py b/glcm_cupy/glcm/glcm.py
index 83b5b21..5a816d7 100644
--- a/glcm_cupy/glcm/glcm.py
+++ b/glcm_cupy/glcm/glcm.py
@@ -36,8 +36,13 @@ def glcm(
                                    Direction.SOUTH_WEST),
     max_partition_size: int = MAX_PARTITION_SIZE,
     max_threads: int = MAX_THREADS,
-    features: Set[int] = (HOMOGENEITY, CONTRAST, ASM,
-                          MEAN, VARIANCE, CORRELATION),
+    features: Set[int] = (Features.HOMOGENEITY,
+                          Features.CONTRAST,
+                          Features.ASM,
+                          Features.MEAN,
+                          Features.VARIANCE,
+                          Features.CORRELATION,
+                          Features.DISSIMILARITY),
     normalized_features: bool = True,
     verbose: bool = True
 ) -> ndarray:
diff --git a/glcm_cupy/glcm_base.py b/glcm_cupy/glcm_base.py
index e050cda..09fa232 100644
--- a/glcm_cupy/glcm_base.py
+++ b/glcm_cupy/glcm_base.py
@@ -11,7 +11,13 @@
 from glcm_cupy.kernel import get_glcm_module
 from glcm_cupy.utils import calc_grid_size, normalize_features, binner
 
-FEATURES = HOMOGENEITY, CONTRAST, ASM, MEAN, VARIANCE, CORRELATION
+FEATURES = Features.HOMOGENEITY, \
+           Features.CONTRAST, \
+           Features.ASM, \
+           Features.MEAN, \
+           Features.VARIANCE, \
+           Features.CORRELATION, \
+           Features.DISSIMILARITY
 
 
 @dataclass
@@ -46,8 +52,13 @@ class GLCMBase:
     bin_to: int = 256
     max_partition_size: int = MAX_PARTITION_SIZE
     max_threads: int = MAX_THREADS
-    features: Set[int] = (HOMOGENEITY, CONTRAST, ASM,
-                          MEAN, VARIANCE, CORRELATION)
+    features: Set[int] = (Features.HOMOGENEITY,
+                          Features.CONTRAST,
+                          Features.ASM,
+                          Features.MEAN,
+                          Features.VARIANCE,
+                          Features.CORRELATION,
+                          Features.DISSIMILARITY)
     normalized_features: bool = True
     verbose: bool = True
 
@@ -84,12 +95,13 @@ def __post_init__(self):
             )
 
         module = get_glcm_module(
-            HOMOGENEITY in self.features,
-            CONTRAST in self.features,
-            ASM in self.features,
-            MEAN in self.features,
-            VARIANCE in self.features,
-            CORRELATION in self.features
+             homogeneity=Features.HOMOGENEITY in self.features,
+             contrast=Features.CONTRAST in self.features,
+             asm=Features.ASM in self.features,
+             mean=Features.MEAN in self.features,
+             variance=Features.VARIANCE in self.features,
+             correlation=Features.CORRELATION in self.features,
+             dissimilarity=Features.DISSIMILARITY in self.features
         )
         self.glcm_create_kernel = module.get_function('glcmCreateKernel')
         self.glcm_feature_kernel_0 = module.get_function('glcmFeatureKernel0')
@@ -332,16 +344,17 @@ def glcm_ij(self,
     def do_stage(self, stage_no: int) -> bool:
         """ Determines if running the nth stage GLCM is necessary """
         if stage_no == 2:
-            return CORRELATION in self.features
+            return Features.CORRELATION in self.features
         elif stage_no == 1:
-            return VARIANCE in self.features or \
-                   CORRELATION in self.features
+            return Features.VARIANCE in self.features or \
+                   Features.CORRELATION in self.features
         elif stage_no == 0:
             return (
-                HOMOGENEITY in self.features or
-                CONTRAST in self.features or
-                ASM in self.features or
-                MEAN in self.features or
-                VARIANCE in self.features or
-                CORRELATION in self.features
+                Features.HOMOGENEITY in self.features or
+                Features.CONTRAST in self.features or
+                Features.ASM in self.features or
+                Features.MEAN in self.features or
+                Features.VARIANCE in self.features or
+                Features.CORRELATION in self.features or
+                Features.DISSIMILARITY in self.features
             )
diff --git a/glcm_cupy/glcm_py_base.py b/glcm_cupy/glcm_py_base.py
index 2dba2b7..1e91055 100644
--- a/glcm_cupy/glcm_py_base.py
+++ b/glcm_cupy/glcm_py_base.py
@@ -54,9 +54,11 @@ def glcm_ij(self, i: ndarray, j: ndarray) -> List[float]:
         # Convert to probability
         glcm /= len(i_flat) * 2
 
-        homogeneity = contrast = asm = mean = var = correlation = 0
+        homogeneity = contrast = asm = mean = var = \
+            correlation = dissimilarity = 0
         for i in range(glcm.shape[0]):
             for j in range(glcm.shape[1]):
+                dissimilarity += glcm[i, j] * np.abs(i - j)
                 homogeneity += glcm[i, j] / (1 + (i - j) ** 2)
                 contrast += glcm[i, j] * (i - j) ** 2
                 asm += glcm[i, j] ** 2
@@ -72,4 +74,5 @@ def glcm_ij(self, i: ndarray, j: ndarray) -> List[float]:
                 for j in range(glcm.shape[1]):
                     correlation += glcm[i, j] * (i - mean) * (j - mean) / var
 
-        return [homogeneity, contrast, asm, mean, var, correlation]
+        return [homogeneity, contrast, asm, mean, var, correlation,
+                dissimilarity]
diff --git a/glcm_cupy/kernel.py b/glcm_cupy/kernel.py
index 3dad857..4fa0d55 100644
--- a/glcm_cupy/kernel.py
+++ b/glcm_cupy/kernel.py
@@ -44,13 +44,22 @@
 );
 """
 
+
+DISSIMILARITY_FN = """
+atomicAdd(
+    &features[DISSIMILARITY + wid * NO_OF_FEATURES],
+    p * abs(i - j)
+);
+"""
+
 def get_glcm_module(
     homogeneity = True,
     contrast = True,
     asm = True,
     mean = True,
     variance = True,
-    correlation = True
+    correlation = True,
+    dissimilarity = True
 ):
     if correlation:
         variance = True
@@ -64,7 +73,8 @@ def get_glcm_module(
 #define MEAN 3
 #define VAR 4
 #define CORRELATION 5
-#define NO_OF_FEATURES 6
+#define DISSIMILARITY 6
+#define NO_OF_FEATURES 7
 
 extern "C" {{
     __global__ void glcmCreateKernel(
@@ -234,6 +244,7 @@ def get_glcm_module(
         | MEAN           | | MEAN           | | MEAN           |
         | VAR            | | VAR            | | VAR            |
         | CORRELATION    | | CORRELATION    | | CORRELATION    |
+        | DISSIMILARITY  | | DISSIMILARITY  | | DISSIMILARITY  | 
         +----------------+ +----------------+ +----------------+
         Window 0           Window 1           Window 2           ...
         **/
@@ -243,6 +254,7 @@ def get_glcm_module(
         {CONTRAST_FN if contrast else ""}
         {ASM_FN if asm else ""}
         {MEAN_FN if mean else ""}
+        {DISSIMILARITY_FN if dissimilarity else ""}
     }}
     __global__ void glcmFeatureKernel1(
         const float* g,
diff --git a/glcm_cupy/utils.py b/glcm_cupy/utils.py
index 2a7c239..fdd50aa 100644
--- a/glcm_cupy/utils.py
+++ b/glcm_cupy/utils.py
@@ -7,11 +7,12 @@
 
 def normalize_features(ar: ndarray, bin_to: int) -> ndarray:
     """ This scales the glcm features to [0, 1] """
-    ar[..., CONTRAST] /= (bin_to - 1) ** 2
-    ar[..., MEAN] /= (bin_to - 1)
-    ar[..., VARIANCE] /= (bin_to - 1) ** 2
-    ar[..., CORRELATION] += 1
-    ar[..., CORRELATION] /= 2
+    ar[..., Features.CONTRAST] /= (bin_to - 1) ** 2
+    ar[..., Features.MEAN] /= (bin_to - 1)
+    ar[..., Features.VARIANCE] /= (bin_to - 1) ** 2
+    ar[..., Features.CORRELATION] += 1
+    ar[..., Features.CORRELATION] /= 2
+    ar[..., Features.DISSIMILARITY] /= (bin_to - 1)
     return ar
 
 
diff --git a/sphinx/build/doctrees/batch_processing.doctree b/sphinx/build/doctrees/batch_processing.doctree
index ca3ec81..8ff344e 100644
Binary files a/sphinx/build/doctrees/batch_processing.doctree and b/sphinx/build/doctrees/batch_processing.doctree differ
diff --git a/sphinx/build/doctrees/changelog.doctree b/sphinx/build/doctrees/changelog.doctree
index f52271d..15c28d4 100644
Binary files a/sphinx/build/doctrees/changelog.doctree and b/sphinx/build/doctrees/changelog.doctree differ
diff --git a/sphinx/build/doctrees/environment.pickle b/sphinx/build/doctrees/environment.pickle
index ec171ee..2891750 100644
Binary files a/sphinx/build/doctrees/environment.pickle and b/sphinx/build/doctrees/environment.pickle differ
diff --git a/sphinx/build/doctrees/features.doctree b/sphinx/build/doctrees/features.doctree
index f1bfcb3..fe51f3c 100644
Binary files a/sphinx/build/doctrees/features.doctree and b/sphinx/build/doctrees/features.doctree differ
diff --git a/sphinx/build/html/_sources/batch_processing.rst.txt b/sphinx/build/html/_sources/batch_processing.rst.txt
index 6351fc5..bfb5628 100644
--- a/sphinx/build/html/_sources/batch_processing.rst.txt
+++ b/sphinx/build/html/_sources/batch_processing.rst.txt
@@ -20,7 +20,7 @@ This is slightly faster on ``GLCM``, it will start on the next image while the c
     >>> # This is why you need them to be the same size
     >>> g = GLCM(np.stack([ar0, ar1])).run(ar)
     >>> g.shape
-    (2, 1074, 1914, 3, 6)
+    (2, 1074, 1914, 3, 7)
     >>> g0, g1 = g[0], g[1]
 
 The dimensions here are ``(batch, height, width, channel, features)``.
@@ -36,7 +36,7 @@ GLCMCross
 
     >>> g = GLCMCross(np.stack([ar0, ar1])).run(ar)
     >>> g.shape
-    (2, 1074, 1914, 3, 6)
+    (2, 1074, 1914, 3, 7)
     >>> g0, g1 = g[0], g[1]
 
 Behavior of the ``ix_combos`` specified does not change.
diff --git a/sphinx/build/html/_sources/changelog.rst.txt b/sphinx/build/html/_sources/changelog.rst.txt
index a909f34..f8532c1 100644
--- a/sphinx/build/html/_sources/changelog.rst.txt
+++ b/sphinx/build/html/_sources/changelog.rst.txt
@@ -33,4 +33,6 @@ Changelog
 - Implemented GLCM Feature Selection to optimize out unnecessary GLCM Stages
 - Fix issue with CuPy ndarray incompatible with tqdm
 - Add Batch Processing for vanilla GLCM
-    - ``GLCMCross`` doesn't perform faster with this. However is compatible.
\ No newline at end of file
+    - ``GLCMCross`` doesn't perform faster with this. However is compatible.
+- Implement Dissimilarity Feature
+
diff --git a/sphinx/build/html/_sources/features.rst.txt b/sphinx/build/html/_sources/features.rst.txt
index afb8aad..e9a17e4 100644
--- a/sphinx/build/html/_sources/features.rst.txt
+++ b/sphinx/build/html/_sources/features.rst.txt
@@ -44,7 +44,8 @@ In total, we have 6 features.
     \text{Angular Second Moment (ASM)} = \sum_{i,j=0}^{N-1}P_{i,j}^2\\
     \text{GLCM Mean, } \mu = \sum_{i,j=0}^{N-1}i * P_{i,j}\\
     \text{GLCM Variance, } \sigma^2 = \sum_{i,j=0}^{N-1}P_{i,j}(i - \mu_i)^2\\
-    \text{Correlation} = \frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+    \text{Correlation} = \sum_{i,j=0}^{N-1}P_{i,j}\frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+    \text{Dissimilarity} = \sum_{i,j=0}^{N-1}P_{i,j} * \left\lvert i - j \right\rvert\\
 
 We implemented these few as they are the most orthogonal (according to the tutorial).
 However, feel free to suggest any more in the GitHub Issue page.
diff --git a/sphinx/build/html/batch_processing.html b/sphinx/build/html/batch_processing.html
index 288158a..0560bdb 100644
--- a/sphinx/build/html/batch_processing.html
+++ b/sphinx/build/html/batch_processing.html
@@ -173,7 +173,7 @@ <h1>Batch Processing<a class="headerlink" href="#batch-processing" title="Permal
 <span class="gp">&gt;&gt;&gt; </span><span class="c1"># This is why you need them to be the same size</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g</span> <span class="o">=</span> <span class="n">GLCM</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">([</span><span class="n">ar0</span><span class="p">,</span> <span class="n">ar1</span><span class="p">]))</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">ar</span><span class="p">)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g</span><span class="o">.</span><span class="n">shape</span>
-<span class="go">(2, 1074, 1914, 3, 6)</span>
+<span class="go">(2, 1074, 1914, 3, 7)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g0</span><span class="p">,</span> <span class="n">g1</span> <span class="o">=</span> <span class="n">g</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">g</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
 </pre></div>
 </div>
@@ -184,7 +184,7 @@ <h2>GLCMCross<a class="headerlink" href="#glcmcross" title="Permalink to this he
 <p><code class="docutils literal notranslate"><span class="pre">GLCMCross</span></code> does not benefit in speed, however it may be simpler in syntax.</p>
 <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">g</span> <span class="o">=</span> <span class="n">GLCMCross</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">([</span><span class="n">ar0</span><span class="p">,</span> <span class="n">ar1</span><span class="p">]))</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">ar</span><span class="p">)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g</span><span class="o">.</span><span class="n">shape</span>
-<span class="go">(2, 1074, 1914, 3, 6)</span>
+<span class="go">(2, 1074, 1914, 3, 7)</span>
 <span class="gp">&gt;&gt;&gt; </span><span class="n">g0</span><span class="p">,</span> <span class="n">g1</span> <span class="o">=</span> <span class="n">g</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">g</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
 </pre></div>
 </div>
diff --git a/sphinx/build/html/changelog.html b/sphinx/build/html/changelog.html
index 5cfae64..501b5d5 100644
--- a/sphinx/build/html/changelog.html
+++ b/sphinx/build/html/changelog.html
@@ -223,6 +223,7 @@ <h2>1.10<a class="headerlink" href="#id8" title="Permalink to this headline">¶<
 </dd>
 </dl>
 </li>
+<li><p>Implement Dissimilarity Feature</p></li>
 </ul>
 </div>
 </div>
diff --git a/sphinx/build/html/features.html b/sphinx/build/html/features.html
index 3747b23..ed1c577 100644
--- a/sphinx/build/html/features.html
+++ b/sphinx/build/html/features.html
@@ -95,6 +95,7 @@
 <li class="toctree-l1"><a class="reference internal" href="binning.html">Binning</a></li>
 <li class="toctree-l1"><a class="reference internal" href="direction.html">Direction</a></li>
 <li class="toctree-l1"><a class="reference internal" href="radius_step_size.html">Radius &amp; Step Size</a></li>
+<li class="toctree-l1"><a class="reference internal" href="batch_processing.html">Batch Processing</a></li>
 <li class="toctree-l1"><a class="reference internal" href="acknowledgements.html">Acknowledgements</a></li>
 <li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog</a></li>
 </ul>
@@ -194,7 +195,8 @@ <h2>Feature Theory<a class="headerlink" href="#feature-theory" title="Permalink
 \text{Angular Second Moment (ASM)} = \sum_{i,j=0}^{N-1}P_{i,j}^2\\
 \text{GLCM Mean, } \mu = \sum_{i,j=0}^{N-1}i * P_{i,j}\\
 \text{GLCM Variance, } \sigma^2 = \sum_{i,j=0}^{N-1}P_{i,j}(i - \mu_i)^2\\
-\text{Correlation} = \frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\\end{split}\]</div>
+\text{Correlation} = \sum_{i,j=0}^{N-1}P_{i,j}\frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+\text{Dissimilarity} = \sum_{i,j=0}^{N-1}P_{i,j} * \left\lvert i - j \right\rvert\\\end{split}\]</div>
 <p>We implemented these few as they are the most orthogonal (according to the tutorial).
 However, feel free to suggest any more in the GitHub Issue page.</p>
 </div>
diff --git a/sphinx/build/html/searchindex.js b/sphinx/build/html/searchindex.js
index 08e16a8..4b53d09 100644
--- a/sphinx/build/html/searchindex.js
+++ b/sphinx/build/html/searchindex.js
@@ -1,1 +1,1 @@
-Search.setIndex({docnames:["acknowledgements","batch_processing","binning","changelog","direction","features","glcm_cross","index","radius_step_size"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["acknowledgements.rst","batch_processing.rst","binning.rst","changelog.rst","direction.rst","features.rst","glcm_cross.rst","index.rst","radius_step_size.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,5,6,8],"1":[1,5,6,7,8],"10":7,"1074":[1,7],"1080":[1,6,7],"11":[3,7],"13":3,"15":2,"16":2,"18":3,"1914":[1,7],"1920":[1,6,7],"1st":1,"2":[1,2,5,6],"25":3,"255":2,"256":2,"3":[1,6,7,8],"3rd":6,"4":[2,4],"5":5,"6":[1,5,6,7],"7":7,"8":7,"9":7,"default":7,"do":0,"function":8,"import":[1,2,4,5,6,7,8],"int":8,"return":5,"try":2,"while":1,As:2,By:6,For:7,If:[1,8],In:[5,6],It:[1,7,8],On:4,That:4,The:[1,2,4,6,8],Then:7,To:[2,5,6,7],_:7,__:7,about:7,accord:5,achiev:4,acknowledg:7,ad:4,add:3,after:[0,6],ahead:8,ai:[],algorithm:4,all:[1,6],alwai:3,an:[2,6,7],angular:5,ani:[5,8],ar0:[1,7],ar1:[1,7],ar2:7,ar:[1,2,3,4,5,6,7,8],arg:7,argument:2,articl:7,asarrai:[2,4,6,8],asm:5,automat:7,avail:4,bar:7,batch:[3,7],behavior:1,being:1,benefit:1,benjamin:0,between:[6,8],bi:7,bin:[0,7],bin_from:2,bin_to:2,blank:1,c:7,can:[4,5,6],caution:7,caveat:6,center:8,chang:1,changelog:7,channel:[1,5,6],check:[3,7],com:[],combin:[1,7],compat:3,complex:2,concurr:1,conda:7,consid:[6,7],contrast:[5,6,7,8],correl:[5,7,8],cost:4,cover:4,cross:[3,7],cucim:[3,7],cuda:7,cudatoolkit:7,cupi:3,current:1,cv2:[1,5,7],def:8,defin:8,depend:[3,7],determin:5,diagon:8,diamet:8,dimens:[1,6,7],direct:[2,7],direction:7,distanc:8,doe:[1,5],doesn:3,dr:0,drastic:2,drop:3,e:2,each:[1,6,8],east:4,enabl:7,euclidean:8,ev:[],extend:0,fail:8,faster:[1,3],featur:[1,3,6,7],feel:5,few:5,first:7,fix:3,float32:3,follow:[0,5,6],forg:7,frac:5,free:5,from:[1,2,4,5,6,7,8],g0:[1,7],g1:[1,7],g2:7,g:[1,2,4,5,6,7,8],gap:[4,5],gener:[1,6,7],get:7,github:5,glcm:[1,2,3,4,8],glcm_cross:6,glcm_cupi:[1,2,4,5,6,7,8],glcm_shape:8,glcmcross:[3,6,7],goh:0,gratitud:0,guid:7,ha:8,have:[1,5,7,8],height:1,helper:8,here:[1,4,5],hi:0,higher:2,homogen:5,host:0,howev:[1,3,5,6],html:[],http:[],i:[0,3,4,5,6,7],idea:0,im_shap:8,imag:[1,2,4,5,6,7,8],image_0:1,image_1:1,implement:[0,3,5],imread:[1,5,7],includ:[2,8],incompat:3,increas:2,index:7,indic:6,indirectli:6,input:[2,3],instal:[],instanc:6,integr:3,issu:[3,5],itertool:6,ix_combo:[1,6],j:[3,4,5,6],ji:0,jifei:0,jon:0,jpg:[1,2,4,5,6,7,8],kernel:4,know:8,knowledg:[4,5],last:[6,7],learn:7,left:7,like:[6,7],limit:2,ll:[1,4,8],loop:1,mai:[1,4,6,8],make:3,mani:7,manual:7,max:2,maximum:2,me:[0,7],mean:[4,5],merg:3,moment:5,more:5,most:5,mu:5,mu_i:5,mu_j:5,multipl:1,my:0,n:[2,5],ndarrai:3,need:[0,1,2,7],neglig:4,next:1,ning:[],none:6,normal:5,note:[1,5],np:[1,2,4,6,7,8],numba:0,numpi:[2,4,6,8],o:2,onc:7,onli:6,open:[2,4,6,8],opt:1,optim:3,option:3,order:[5,6],orthogon:5,other:[4,5],out:3,output:3,overflow:3,p_:5,page:5,pars:5,peopl:0,perform:[3,4],pil:[2,4,6,8],pip:7,pixel:8,popul:6,possibl:6,pr:3,print:5,process:[3,7],project:0,properti:6,provid:0,purpos:2,push:0,python:7,radiu:7,rang:6,rapid:[3,7],re:6,readi:2,recommend:[4,5,7],reduc:[2,5],referenc:[4,5],reflect:4,reject:8,relationship:6,replac:7,requir:2,resolv:3,result:8,retriev:[1,5,7],reus:[6,7],run:[1,2,4,5,6,7,8],s:[1,2,4,5,7,8],same:[1,3,7],scale:7,second:5,select:[3,7],separ:6,shape:[1,6,7,8],shape_aft:8,shrink:2,side:7,sigma:5,sigma_i:5,sigma_j:5,signatur:8,simpler:1,simpli:4,sit:0,size:[1,2,7],skip:6,slightli:1,small:8,so:[1,6,7],south:4,south_east:4,south_west:4,specif:5,specifi:[1,4,6],speed:1,spur:0,sqrt:5,stabil:3,stack:[1,7],stage:3,start:1,statist:6,step:7,step_siz:8,still:1,suggest:5,suitabl:7,sum_:5,support:[3,7],syntax:[1,5],t:[3,6],taken:[2,6],test:[2,3],text:5,than:1,thei:5,them:[1,4],theori:7,thi:[0,1,3,4,5,7,8],thu:[2,4,6],time:[5,7,8],too:8,top:4,total:5,tqdm:3,treat:8,tupl:8,tutori:[4,5],unnecessari:3,us:[2,4,5,6,7],valu:[2,8],vanilla:3,variabl:3,varianc:5,version:7,view:7,wang:0,we:[2,4,5,7,8],west:4,when:[2,6],why:1,width:1,window:8,work:7,yield:6,you:[1,4,5,6,7,8],zero:5},titles:["Acknowledgements","Batch Processing","Binning","Changelog","Direction","GLCM Feature Indexing","Cross GLCM","GLCM Implemented in CuPy","Radius &amp; Step Size"],titleterms:{"1":3,"10":3,"6":3,"7":3,"8":3,"9":3,"default":6,acknowledg:0,batch:1,bi:4,bin:2,caution:2,changelog:3,check:8,combin:6,content:7,cross:6,cupi:7,direct:4,direction:4,featur:5,get:5,glcm:[5,6,7],glcmcross:1,implement:7,index:5,instal:7,more:7,option:7,process:1,quick:7,radiu:8,read:7,recommend:2,retriev:6,scale:2,select:[5,6],size:8,start:7,step:8,suitabl:8,theori:5,time:2,usag:[6,7]}})
\ No newline at end of file
+Search.setIndex({docnames:["acknowledgements","batch_processing","binning","changelog","direction","features","glcm_cross","index","radius_step_size"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["acknowledgements.rst","batch_processing.rst","binning.rst","changelog.rst","direction.rst","features.rst","glcm_cross.rst","index.rst","radius_step_size.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,5,6,8],"1":[1,5,6,7,8],"10":7,"1074":[1,7],"1080":[1,6,7],"11":[3,7],"13":3,"15":2,"16":2,"18":3,"1914":[1,7],"1920":[1,6,7],"1st":1,"2":[1,2,5,6],"25":3,"255":2,"256":2,"3":[1,6,7,8],"3rd":6,"4":[2,4],"5":5,"6":[5,6,7],"7":[1,7],"8":7,"9":7,"default":7,"do":0,"function":8,"import":[1,2,4,5,6,7,8],"int":8,"return":5,"try":2,"while":1,As:2,By:6,For:7,If:[1,8],In:[5,6],It:[1,7,8],On:4,That:4,The:[1,2,4,6,8],Then:7,To:[2,5,6,7],_:7,__:7,about:7,accord:5,achiev:4,acknowledg:7,ad:4,add:3,after:[0,6],ahead:8,ai:[],algorithm:4,all:[1,6],alwai:3,an:[2,6,7],angular:5,ani:[5,8],ar0:[1,7],ar1:[1,7],ar2:7,ar:[1,2,3,4,5,6,7,8],arg:7,argument:2,articl:7,asarrai:[2,4,6,8],asm:5,automat:7,avail:4,bar:7,batch:[3,7],behavior:1,being:1,benefit:1,benjamin:0,between:[6,8],bi:7,bin:[0,7],bin_from:2,bin_to:2,blank:1,c:7,can:[4,5,6],caution:7,caveat:6,center:8,chang:1,changelog:7,channel:[1,5,6],check:[3,7],com:[],combin:[1,7],compat:3,complex:2,concurr:1,conda:7,consid:[6,7],contrast:[5,6,7,8],correl:[5,7,8],cost:4,cover:4,cross:[3,7],cucim:[3,7],cuda:7,cudatoolkit:7,cupi:3,current:1,cv2:[1,5,7],def:8,defin:8,depend:[3,7],determin:5,diagon:8,diamet:8,dimens:[1,6,7],direct:[2,7],direction:7,dissimilar:[3,5],distanc:8,doe:[1,5],doesn:3,dr:0,drastic:2,drop:3,e:2,each:[1,6,8],east:4,enabl:7,euclidean:8,ev:[],extend:0,fail:8,faster:[1,3],featur:[1,3,6,7],feel:5,few:5,first:7,fix:3,float32:3,follow:[0,5,6],forg:7,frac:5,free:5,from:[1,2,4,5,6,7,8],g0:[1,7],g1:[1,7],g2:7,g:[1,2,4,5,6,7,8],gap:[4,5],gener:[1,6,7],get:7,github:5,glcm:[1,2,3,4,8],glcm_cross:6,glcm_cupi:[1,2,4,5,6,7,8],glcm_shape:8,glcmcross:[3,6,7],goh:0,gratitud:0,guid:7,ha:8,have:[1,5,7,8],height:1,helper:8,here:[1,4,5],hi:0,higher:2,homogen:5,host:0,howev:[1,3,5,6],html:[],http:[],i:[0,3,4,5,6,7],idea:0,im_shap:8,imag:[1,2,4,5,6,7,8],image_0:1,image_1:1,implement:[0,3,5],imread:[1,5,7],includ:[2,8],incompat:3,increas:2,index:7,indic:6,indirectli:6,input:[2,3],instal:[],instanc:6,integr:3,issu:[3,5],itertool:6,ix_combo:[1,6],j:[3,4,5,6],ji:0,jifei:0,jon:0,jpg:[1,2,4,5,6,7,8],kernel:4,know:8,knowledg:[4,5],last:[6,7],learn:7,left:[5,7],like:[6,7],limit:2,ll:[1,4,8],loop:1,lvert:5,mai:[1,4,6,8],make:3,mani:7,manual:7,max:2,maximum:2,me:[0,7],mean:[4,5],merg:3,moment:5,more:5,most:5,mu:5,mu_i:5,mu_j:5,multipl:1,my:0,n:[2,5],ndarrai:3,need:[0,1,2,7],neglig:4,next:1,ning:[],none:6,normal:5,note:[1,5],np:[1,2,4,6,7,8],numba:0,numpi:[2,4,6,8],o:2,onc:7,onli:6,open:[2,4,6,8],opt:1,optim:3,option:3,order:[5,6],orthogon:5,other:[4,5],out:3,output:3,overflow:3,p_:5,page:5,pars:5,peopl:0,perform:[3,4],pil:[2,4,6,8],pip:7,pixel:8,popul:6,possibl:6,pr:3,print:5,process:[3,7],project:0,properti:6,provid:0,purpos:2,push:0,python:7,radiu:7,rang:6,rapid:[3,7],re:6,readi:2,recommend:[4,5,7],reduc:[2,5],referenc:[4,5],reflect:4,reject:8,relationship:6,replac:7,requir:2,resolv:3,result:8,retriev:[1,5,7],reus:[6,7],right:5,run:[1,2,4,5,6,7,8],rvert:5,s:[1,2,4,5,7,8],same:[1,3,7],scale:7,second:5,select:[3,7],separ:6,shape:[1,6,7,8],shape_aft:8,shrink:2,side:7,sigma:5,sigma_i:5,sigma_j:5,signatur:8,simpler:1,simpli:4,sit:0,size:[1,2,7],skip:6,slightli:1,small:8,so:[1,6,7],south:4,south_east:4,south_west:4,specif:5,specifi:[1,4,6],speed:1,spur:0,sqrt:5,stabil:3,stack:[1,7],stage:3,start:1,statist:6,step:7,step_siz:8,still:1,suggest:5,suitabl:7,sum_:5,support:[3,7],syntax:[1,5],t:[3,6],taken:[2,6],test:[2,3],text:5,than:1,thei:5,them:[1,4],theori:7,thi:[0,1,3,4,5,7,8],thu:[2,4,6],time:[5,7,8],too:8,top:4,total:5,tqdm:3,treat:8,tupl:8,tutori:[4,5],unnecessari:3,us:[2,4,5,6,7],valu:[2,8],vanilla:3,variabl:3,varianc:5,version:7,view:7,wang:0,we:[2,4,5,7,8],west:4,when:[2,6],why:1,width:1,window:8,work:7,yield:6,you:[1,4,5,6,7,8],zero:5},titles:["Acknowledgements","Batch Processing","Binning","Changelog","Direction","GLCM Feature Indexing","Cross GLCM","GLCM Implemented in CuPy","Radius &amp; Step Size"],titleterms:{"1":3,"10":3,"6":3,"7":3,"8":3,"9":3,"default":6,acknowledg:0,batch:1,bi:4,bin:2,caution:2,changelog:3,check:8,combin:6,content:7,cross:6,cupi:7,direct:4,direction:4,featur:5,get:5,glcm:[5,6,7],glcmcross:1,implement:7,index:5,instal:7,more:7,option:7,process:1,quick:7,radiu:8,read:7,recommend:2,retriev:6,scale:2,select:[5,6],size:8,start:7,step:8,suitabl:8,theori:5,time:2,usag:[6,7]}})
\ No newline at end of file
diff --git a/sphinx/src/batch_processing.rst b/sphinx/src/batch_processing.rst
index 6351fc5..bfb5628 100644
--- a/sphinx/src/batch_processing.rst
+++ b/sphinx/src/batch_processing.rst
@@ -20,7 +20,7 @@ This is slightly faster on ``GLCM``, it will start on the next image while the c
     >>> # This is why you need them to be the same size
     >>> g = GLCM(np.stack([ar0, ar1])).run(ar)
     >>> g.shape
-    (2, 1074, 1914, 3, 6)
+    (2, 1074, 1914, 3, 7)
     >>> g0, g1 = g[0], g[1]
 
 The dimensions here are ``(batch, height, width, channel, features)``.
@@ -36,7 +36,7 @@ GLCMCross
 
     >>> g = GLCMCross(np.stack([ar0, ar1])).run(ar)
     >>> g.shape
-    (2, 1074, 1914, 3, 6)
+    (2, 1074, 1914, 3, 7)
     >>> g0, g1 = g[0], g[1]
 
 Behavior of the ``ix_combos`` specified does not change.
diff --git a/sphinx/src/changelog.rst b/sphinx/src/changelog.rst
index a909f34..f8532c1 100644
--- a/sphinx/src/changelog.rst
+++ b/sphinx/src/changelog.rst
@@ -33,4 +33,6 @@ Changelog
 - Implemented GLCM Feature Selection to optimize out unnecessary GLCM Stages
 - Fix issue with CuPy ndarray incompatible with tqdm
 - Add Batch Processing for vanilla GLCM
-    - ``GLCMCross`` doesn't perform faster with this. However is compatible.
\ No newline at end of file
+    - ``GLCMCross`` doesn't perform faster with this. However is compatible.
+- Implement Dissimilarity Feature
+
diff --git a/sphinx/src/features.rst b/sphinx/src/features.rst
index afb8aad..e9a17e4 100644
--- a/sphinx/src/features.rst
+++ b/sphinx/src/features.rst
@@ -44,7 +44,8 @@ In total, we have 6 features.
     \text{Angular Second Moment (ASM)} = \sum_{i,j=0}^{N-1}P_{i,j}^2\\
     \text{GLCM Mean, } \mu = \sum_{i,j=0}^{N-1}i * P_{i,j}\\
     \text{GLCM Variance, } \sigma^2 = \sum_{i,j=0}^{N-1}P_{i,j}(i - \mu_i)^2\\
-    \text{Correlation} = \frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+    \text{Correlation} = \sum_{i,j=0}^{N-1}P_{i,j}\frac{(i - \mu_i)(j - \mu_j)}{\sqrt{\sigma_i^2\sigma_j^2}}\\
+    \text{Dissimilarity} = \sum_{i,j=0}^{N-1}P_{i,j} * \left\lvert i - j \right\rvert\\
 
 We implemented these few as they are the most orthogonal (according to the tutorial).
 However, feel free to suggest any more in the GitHub Issue page.


Test patch:
diff --git a/tests/integration_tests/expected/ar_2d_glcm.npy b/tests/integration_tests/expected/ar_2d_glcm.npy
index 95c17a1..2f46d0a 100644
Binary files a/tests/integration_tests/expected/ar_2d_glcm.npy and b/tests/integration_tests/expected/ar_2d_glcm.npy differ
diff --git a/tests/integration_tests/expected/ar_3d_combo_glcm_cross.npy b/tests/integration_tests/expected/ar_3d_combo_glcm_cross.npy
index 3a61bd5..d6afff2 100644
Binary files a/tests/integration_tests/expected/ar_3d_combo_glcm_cross.npy and b/tests/integration_tests/expected/ar_3d_combo_glcm_cross.npy differ
diff --git a/tests/integration_tests/expected/ar_3d_glcm.npy b/tests/integration_tests/expected/ar_3d_glcm.npy
index 960c156..481d3f5 100644
Binary files a/tests/integration_tests/expected/ar_3d_glcm.npy and b/tests/integration_tests/expected/ar_3d_glcm.npy differ
diff --git a/tests/integration_tests/expected/ar_3d_glcm_cross.npy b/tests/integration_tests/expected/ar_3d_glcm_cross.npy
index c52637a..8146535 100644
Binary files a/tests/integration_tests/expected/ar_3d_glcm_cross.npy and b/tests/integration_tests/expected/ar_3d_glcm_cross.npy differ
diff --git a/tests/integration_tests/expected/glcm_cross_image.npy b/tests/integration_tests/expected/glcm_cross_image.npy
index 8d5faff..afc13c7 100644
Binary files a/tests/integration_tests/expected/glcm_cross_image.npy and b/tests/integration_tests/expected/glcm_cross_image.npy differ
diff --git a/tests/integration_tests/expected/glcm_image.npy b/tests/integration_tests/expected/glcm_image.npy
index 1b2557d..68c2aa3 100644
Binary files a/tests/integration_tests/expected/glcm_image.npy and b/tests/integration_tests/expected/glcm_image.npy differ
diff --git a/tests/integration_tests/test_glcm.py b/tests/integration_tests/test_glcm.py
index 5f40c59..c1d3c25 100644
--- a/tests/integration_tests/test_glcm.py
+++ b/tests/integration_tests/test_glcm.py
@@ -1,42 +1,45 @@
 import inspect
+from pathlib import Path
 
 import numpy as np
 import pytest
 
 from glcm_cupy import GLCM, glcm
 
+THIS_DIR = Path(__file__).parent
+
 
 def test_from_3dimage(ar_3d):
     """ Tests using a 3D Image """
     g = GLCM().run(ar_3d)
-    g_exp = np.load("expected/ar_3d_glcm.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_3d_glcm.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_from_2dimage(ar_2d):
     """ Tests with a 2D Image (1 Channel) """
     g = GLCM().run(ar_2d[..., np.newaxis])
-    g_exp = np.load("expected/ar_2d_glcm.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_2d_glcm.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_output_match(ar_3d):
     """ Tests if class & function outputs match """
-    assert GLCM().run(ar_3d) == pytest.approx(glcm(ar_3d), abs=1e-06)
+    assert GLCM().run(ar_3d) == pytest.approx(glcm(ar_3d), abs=1e-04)
 
 
 def test_from_3dimage_cp(ar_3d_cp):
     """ Tests using a 3D Image """
     g = GLCM().run(ar_3d_cp)
-    g_exp = np.load("expected/ar_3d_glcm.npy")
-    assert g.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_3d_glcm.npy")
+    assert g.get() == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_from_2dimage_cp(ar_2d_cp):
     """ Tests with a 2D Image (1 Channel) """
     g = GLCM().run(ar_2d_cp[..., np.newaxis])
-    g_exp = np.load("expected/ar_2d_glcm.npy")
-    assert g.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_2d_glcm.npy")
+    assert g.get() == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_output_match_cp(ar_3d_cp):
@@ -44,7 +47,7 @@ def test_output_match_cp(ar_3d_cp):
     # XXX: pytest.approx does not support CuPy.
     # It needs to get the NumPy array instead.
     assert GLCM().run(ar_3d_cp).get() == \
-           pytest.approx(glcm(ar_3d_cp).get(), abs=1e-06)
+           pytest.approx(glcm(ar_3d_cp).get(), abs=1e-04)
 
 
 def test_signature_match():
diff --git a/tests/integration_tests/test_glcm_cross.py b/tests/integration_tests/test_glcm_cross.py
index a07cde0..d4baba5 100644
--- a/tests/integration_tests/test_glcm_cross.py
+++ b/tests/integration_tests/test_glcm_cross.py
@@ -1,23 +1,26 @@
 import inspect
+from pathlib import Path
 
 import numpy as np
 import pytest
 
 from glcm_cupy import GLCMCross, glcm_cross
 
+THIS_DIR = Path(__file__).parent
+
 
 def test_from_3dimage(ar_3d):
     """ Tests using a 3D Image """
     g = GLCMCross().run(ar_3d)
-    g_exp = np.load("expected/ar_3d_glcm_cross.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_3d_glcm_cross.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_from_3dimage_ix_combo(ar_3d):
     """ Tests using a 3D Image with selected ix_combos """
     g = GLCMCross(ix_combos=[[0, 1], [1, 2]]).run(ar_3d)
-    g_exp = np.load("expected/ar_3d_combo_glcm_cross.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_3d_combo_glcm_cross.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
     assert g.shape[2] == 2
 
 
@@ -32,21 +35,21 @@ def test_from_2dimage(ar_2d):
 def test_output_match(ar_3d):
     """ Tests if class & function outputs match """
     assert GLCMCross().run(ar_3d) == pytest.approx(glcm_cross(ar_3d),
-                                                   abs=1e-06)
+                                                   abs=1e-04)
 
 
 def test_from_3dimage_cp(ar_3d_cp):
     """ Tests using a 3D Image """
     g = GLCMCross().run(ar_3d_cp)
-    g_exp = np.load("expected/ar_3d_glcm_cross.npy")
-    assert g.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_3d_glcm_cross.npy")
+    assert g.get() == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_from_3dimage_ix_combo_cp(ar_3d_cp):
     """ Tests using a 3D Image with selected ix_combos """
     g = GLCMCross(ix_combos=[[0, 1], [1, 2]]).run(ar_3d_cp)
-    g_exp = np.load("expected/ar_3d_combo_glcm_cross.npy")
-    assert g.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/ar_3d_combo_glcm_cross.npy")
+    assert g.get() == pytest.approx(g_exp, abs=1e-04)
     assert g.shape[2] == 2
 
 
@@ -63,7 +66,7 @@ def test_output_match_cp(ar_3d_cp):
     # XXX: pytest.approx does not support CuPy.
     # It needs to get the NumPy array instead.
     assert GLCMCross().run(ar_3d_cp).get() == \
-           pytest.approx(glcm_cross(ar_3d_cp).get(), abs=1e-06)
+           pytest.approx(glcm_cross(ar_3d_cp).get(), abs=1e-04)
 
 
 def test_signature_match():
diff --git a/tests/integration_tests/test_glcm_cross_image.py b/tests/integration_tests/test_glcm_cross_image.py
index 361b194..aa5bdc5 100644
--- a/tests/integration_tests/test_glcm_cross_image.py
+++ b/tests/integration_tests/test_glcm_cross_image.py
@@ -1,19 +1,23 @@
+from pathlib import Path
+
 import cupy as cp
 import numpy as np
 import pytest
 
 from glcm_cupy import GLCMCross
 
+THIS_DIR = Path(__file__).parent
+
 
 def test_glcm_cross_image(ar_img_3d):
     ar = ar_img_3d[::20, ::20]
     g = GLCMCross(bin_to=16).run(ar)
-    g_exp = np.load("expected/glcm_cross_image.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_cross_image.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_glcm_cross_image_cupy(ar_img_3d):
     ar = cp.asarray(ar_img_3d)[::20, ::20]
     g = GLCMCross(bin_to=16).run(ar)
-    g_exp = np.load("expected/glcm_cross_image.npy")
-    assert g.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_cross_image.npy")
+    assert g.get() == pytest.approx(g_exp, abs=1e-04)
diff --git a/tests/integration_tests/test_glcm_cross_image_batch.py b/tests/integration_tests/test_glcm_cross_image_batch.py
index 4572026..22da3b2 100644
--- a/tests/integration_tests/test_glcm_cross_image_batch.py
+++ b/tests/integration_tests/test_glcm_cross_image_batch.py
@@ -1,23 +1,27 @@
+from pathlib import Path
+
 import cupy as cp
 import numpy as np
 import pytest
 
 from glcm_cupy import GLCMCross
 
+THIS_DIR = Path(__file__).parent
+
 
 def test_glcm_cross_image(ar_img_3d):
     ar = np.asarray(ar_img_3d)[::20, ::20]
     g = GLCMCross(bin_to=16).run(np.stack([ar, ar]))
     g0, g1 = g[0], g[1]
-    g_exp = np.load("expected/glcm_cross_image.npy")
-    assert g0 == pytest.approx(g_exp, abs=1e-06)
-    assert g1 == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_cross_image.npy")
+    assert g0 == pytest.approx(g_exp, abs=1e-04)
+    assert g1 == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_glcm_cross_image_cupy(ar_img_3d):
     ar = cp.asarray(ar_img_3d)[::20, ::20]
     g = GLCMCross(bin_to=16).run(cp.stack([ar, ar]))
     g0, g1 = g[0], g[1]
-    g_exp = np.load("expected/glcm_cross_image.npy")
-    assert g0.get() == pytest.approx(g_exp, abs=1e-06)
-    assert g1.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_cross_image.npy")
+    assert g0.get() == pytest.approx(g_exp, abs=1e-04)
+    assert g1.get() == pytest.approx(g_exp, abs=1e-04)
diff --git a/tests/integration_tests/test_glcm_image.py b/tests/integration_tests/test_glcm_image.py
index d8b5c3e..198427e 100644
--- a/tests/integration_tests/test_glcm_image.py
+++ b/tests/integration_tests/test_glcm_image.py
@@ -1,19 +1,23 @@
+from pathlib import Path
+
 import cupy as cp
 import numpy as np
 import pytest
 
 from glcm_cupy import GLCM
 
+THIS_DIR = Path(__file__).parent
+
 
 def test_glcm_image(ar_img_3d):
     ar = ar_img_3d[::20, ::20]
     g = GLCM(bin_to=16).run(ar)
-    g_exp = np.load("expected/glcm_image.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_image.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_glcm_image_cupy(ar_img_3d):
     ar = cp.asarray(ar_img_3d)[::20, ::20]
     g = GLCM(bin_to=16).run(ar)
-    g_exp = np.load("expected/glcm_image.npy")
-    assert g.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_image.npy")
+    assert g.get() == pytest.approx(g_exp, abs=1e-04)
diff --git a/tests/integration_tests/test_glcm_image_batch.py b/tests/integration_tests/test_glcm_image_batch.py
index 6909c93..f37e7fa 100644
--- a/tests/integration_tests/test_glcm_image_batch.py
+++ b/tests/integration_tests/test_glcm_image_batch.py
@@ -1,8 +1,12 @@
+from pathlib import Path
+
 import cupy as cp
 import numpy as np
 import pytest
 
-from glcm_cupy import GLCM, glcm
+from glcm_cupy import GLCM
+
+THIS_DIR = Path(__file__).parent
 
 
 def test_glcm_image(ar_img_3d):
@@ -10,16 +14,16 @@ def test_glcm_image(ar_img_3d):
     g = GLCM(bin_to=16).run(np.stack([ar, ar]))
     g0, g1 = g[0], g[1]
     g = GLCM(bin_to=16).run(ar)
-    g_exp = np.load("expected/glcm_image.npy")
-    assert g == pytest.approx(g_exp, abs=1e-06)
-    assert g0 == pytest.approx(g_exp, abs=1e-06)
-    assert g1 == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_image.npy")
+    assert g == pytest.approx(g_exp, abs=1e-04)
+    assert g0 == pytest.approx(g_exp, abs=1e-04)
+    assert g1 == pytest.approx(g_exp, abs=1e-04)
 
 
 def test_glcm_image_cupy(ar_img_3d):
     ar = cp.asarray(ar_img_3d)[::20, ::20]
     g = GLCM(bin_to=16).run(cp.stack([ar, ar]))
     g0, g1 = g[0], g[1]
-    g_exp = np.load("expected/glcm_image.npy")
-    assert g0.get() == pytest.approx(g_exp, abs=1e-06)
-    assert g1.get() == pytest.approx(g_exp, abs=1e-06)
+    g_exp = np.load(THIS_DIR / "expected/glcm_image.npy")
+    assert g0.get() == pytest.approx(g_exp, abs=1e-04)
+    assert g1.get() == pytest.approx(g_exp, abs=1e-04)
diff --git a/tests/unit_tests/test_glcm.py b/tests/unit_tests/test_glcm.py
index 7fd3f45..67496c0 100644
--- a/tests/unit_tests/test_glcm.py
+++ b/tests/unit_tests/test_glcm.py
@@ -5,6 +5,25 @@
 from glcm_cupy.glcm.glcm_py import glcm_py_im
 
 
+@pytest.mark.parametrize(
+    "ar",
+    [
+        np.ones([16, 16, 3]) * 31,
+        np.zeros([16, 16, 3])
+    ]
+)
+def test_glcm_normalize(ar):
+    """ Assert that our normalize will reduce the range to 0, 1 """
+    g = GLCM(radius=3, bin_from=32, bin_to=32,
+             normalized_features=False).run(ar)
+    assert g.max() >= 1
+    assert g.min() >= 0
+    g = GLCM(radius=3, bin_from=32, bin_to=32,
+             normalized_features=True).run(ar)
+    assert g.min() >= 0
+    assert g.max() <= 1
+
+
 @pytest.mark.parametrize(
     "size",
     [15, ]
@@ -36,4 +55,4 @@ def test_channel_independence():
     g0 = glcm.run(ar0)
     g1 = glcm.run(ar1)
     g_exp = np.concatenate([g0, g1], axis=2)
-    assert g == pytest.approx(g_exp, abs=1e-06)
+    assert g == pytest.approx(g_exp, abs=1e-05)
diff --git a/tests/unit_tests/test_glcm_4d.py b/tests/unit_tests/test_glcm_4d.py
index c1886da..f7349d5 100644
--- a/tests/unit_tests/test_glcm_4d.py
+++ b/tests/unit_tests/test_glcm_4d.py
@@ -28,7 +28,7 @@ def test_glcm_4d(size, bins, radius, batches):
     glcm = GLCM(radius=radius, bin_from=bins, bin_to=bins)
     g_batch = glcm.run(ar_batch)
     g = np.stack([glcm.run(ar) for ar in ar_batch])
-    assert g == pytest.approx(g_batch, abs=1e-06)
+    assert g == pytest.approx(g_batch, abs=1e-05)
 
 
 @pytest.mark.parametrize(
@@ -54,4 +54,4 @@ def test_glcm_4d_cp(size, bins, radius, batches):
     glcm = GLCM(radius=radius, bin_from=bins, bin_to=bins)
     g_batch = glcm.run(ar_batch)
     g = cp.stack([glcm.run(ar) for ar in ar_batch])
-    assert g.get() == pytest.approx(g_batch.get(), abs=1e-06)
+    assert g.get() == pytest.approx(g_batch.get(), abs=1e-05)
diff --git a/tests/unit_tests/test_glcm_base.py b/tests/unit_tests/test_glcm_base.py
index 32ce5b1..2cec15e 100644
--- a/tests/unit_tests/test_glcm_base.py
+++ b/tests/unit_tests/test_glcm_base.py
@@ -34,12 +34,13 @@ def test_glcm_ij(i, j):
 
     # The sum of the values, since tiled, will be scaled by no of windows.
     actual = [
-        float(g[..., HOMOGENEITY].sum() / windows),
-        float(g[..., CONTRAST].sum() / windows),
-        float(g[..., ASM].sum() / windows),
-        float(g[..., MEAN].sum() / windows),
-        float(g[..., VARIANCE].sum() / windows),
-        float(g[..., CORRELATION].sum() / windows)
+        float(g[..., Features.HOMOGENEITY].sum() / windows),
+        float(g[..., Features.CONTRAST].sum() / windows),
+        float(g[..., Features.ASM].sum() / windows),
+        float(g[..., Features.MEAN].sum() / windows),
+        float(g[..., Features.VARIANCE].sum() / windows),
+        float(g[..., Features.CORRELATION].sum() / windows),
+        float(g[..., Features.DISSIMILARITY].sum() / windows)
     ]
 
     expected = glcm_py_ij(i, j, 256, 256)
@@ -47,10 +48,11 @@ def test_glcm_ij(i, j):
 
     # The sum of the values, since tiled, will be scaled by no of windows.
     actual_skimage = dict(
-        homogeneity=float(g[..., HOMOGENEITY].sum() / windows),
-        contrast=float(g[..., CONTRAST].sum() / windows),
-        asm=float(g[..., ASM].sum() / windows),
-        correlation=float(g[..., CORRELATION].sum() / windows)
+        homogeneity=float(g[..., Features.HOMOGENEITY].sum() / windows),
+        contrast=float(g[..., Features.CONTRAST].sum() / windows),
+        asm=float(g[..., Features.ASM].sum() / windows),
+        correlation=float(g[..., Features.CORRELATION].sum() / windows),
+        dissimilarity=float(g[..., Features.DISSIMILARITY].sum() / windows)
     )
 
     if (i == j).all():
diff --git a/tests/unit_tests/test_glcm_cross_4d.py b/tests/unit_tests/test_glcm_cross_4d.py
index 7043074..512c98b 100644
--- a/tests/unit_tests/test_glcm_cross_4d.py
+++ b/tests/unit_tests/test_glcm_cross_4d.py
@@ -27,7 +27,7 @@ def test_glcm_4d(size, bins, radius, batches):
     glcm = GLCMCross(radius=radius, bin_from=bins, bin_to=bins)
     g_batch = glcm.run(ar_batch)
     g = np.stack([glcm.run(ar) for ar in ar_batch])
-    assert g == pytest.approx(g_batch, abs=1e-06)
+    assert g == pytest.approx(g_batch, abs=1e-05)
 
 
 @pytest.mark.parametrize(
@@ -52,4 +52,4 @@ def test_glcm_4d_cp(size, bins, radius, batches):
     glcm = GLCMCross(radius=radius, bin_from=bins, bin_to=bins)
     g_batch = glcm.run(ar_batch)
     g = cp.stack([glcm.run(ar) for ar in ar_batch])
-    assert g.get() == pytest.approx(g_batch.get(), abs=1e-06)
+    assert g.get() == pytest.approx(g_batch.get(), abs=1e-05)
diff --git a/tests/unit_tests/test_glcm_feature_select.py b/tests/unit_tests/test_glcm_feature_select.py
index b90c821..8c61232 100644
--- a/tests/unit_tests/test_glcm_feature_select.py
+++ b/tests/unit_tests/test_glcm_feature_select.py
@@ -3,7 +3,7 @@
 import numpy as np
 import pytest
 
-from glcm_cupy import GLCM, MEAN, VARIANCE, CORRELATION
+from glcm_cupy import GLCM, Features
 from glcm_cupy.glcm_base import FEATURES
 
 
@@ -28,10 +28,10 @@ def test_glcm_feature_select(features):
         g = GLCM(radius=3, bin_from=256,
                  bin_to=16, features=features,
                  normalized_features=False).run(ar)
-        if CORRELATION in features:
-            features.add(VARIANCE)
-        if VARIANCE in features:
-            features.add(MEAN)
+        if Features.CORRELATION in features:
+            features.add(Features.VARIANCE)
+        if Features.VARIANCE in features:
+            features.add(Features.MEAN)
         features = tuple(features)
 
         assert (g[..., features] != 0).flatten().all()
diff --git a/tests/unit_tests/util/glcm_py_skimage.py b/tests/unit_tests/util/glcm_py_skimage.py
index 44b6ea7..0665a5f 100644
--- a/tests/unit_tests/util/glcm_py_skimage.py
+++ b/tests/unit_tests/util/glcm_py_skimage.py
@@ -20,10 +20,12 @@ def glcm_py_skimage(i, j):
     homogeneity = float(greycoprops(glcm, 'homogeneity').squeeze())
     asm = float(greycoprops(glcm, 'ASM').squeeze())
     correlation = float(greycoprops(glcm, 'correlation').squeeze())
+    dissimilarity = float(greycoprops(glcm, 'dissimilarity').squeeze())
 
     return dict(
         homogeneity=homogeneity,
         contrast=contrast,
         asm=asm,
-        correlation=correlation
+        correlation=correlation,
+        dissimilarity=dissimilarity
     )