2

I get several app icons and resize to 36*36. I hope to get similarity between any two of them. I have made them black and white with opencv function threshold. I follow instruction from other questions. I apply matchTemplate with method TM_CCOEFF_NORMED on two icons but get a negative result, which makes me confused. Based on doc there should not be any negative number in result array. Could anyone explain to me that why I get a negative number and does this negative make sense?

enter image description here

I failed one hour for trying edit my post with code indent error, even if I remove all code part from my edit. That's crazy. I have tried both grayscale and black&white of icon. When two icons are quite different, I will always get negative result.

If I use original icon with size 48*48, thing goes well. I don't know whether it is related with my resize step.

#read in pics
im1 = cv2.imread('./app_icon/pacrdt1.png')
im1g = cv2.resize(cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY), (36, 36), cv2.INTER_CUBIC)
im2 = cv2.imread('./app_icon/pacrdt2.png')
im2g = cv2.resize(cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY), (36, 36), cv2.INTER_CUBIC)
im3 = cv2.imread('./app_icon/mny.png')
im3g = cv2.resize(cv2.cvtColor(im3, cv2.COLOR_BGR2GRAY), (36, 36), cv2.INTER_CUBIC)
#black&white convert
(thresh1, bw1) = cv2.threshold(im1g, 128 , 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
(thresh3, bw3) = cv2.threshold(im3g, 128 , 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
(thresh2, bw2) = cv2.threshold(im2g, 128 , 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
#match template
templ_match = cv2.matchTemplate(im1g, im3g, cv2.TM_CCOEFF_NORMED)[0][0]
templ_diff = 1 - templ_match


sample:

enter image description here

enter image description here

enter image description here


edit2: I define icons with different background color or font color as quite similar ones(but viewer will know they are quite same like image 1 and 2 in my sample). That the reason why I input icon picture as black&white. Hope this make sense.

G_cy
  • 994
  • 3
  • 13
  • 28
  • can you post your code and sample images please – noone Jun 19 '18 at 17:28
  • Why convert it to black / white image? Try the same with images in grayscale. – Jeru Luke Jun 19 '18 at 17:42
  • @JeruLuke actually I have tried grayscale and b&w. I will still get negative result. – G_cy Jun 20 '18 at 02:40
  • @G_cy Can you share some sample images? – Jeru Luke Jun 20 '18 at 10:09
  • @JeruLuke thx for your kind help. I add some samples. Could I know how you edit the post? I keep getting error even I can get proper preview. thx – G_cy Jun 20 '18 at 11:31
  • @G_cy Please have a look at the answer – Jeru Luke Jun 21 '18 at 06:16
  • Just for clarity. I came across this thread and found the answer to my question. But the answer is at the end! And not easy to find. The methods cv2.TM_SQDIFF and cv2.TM_SQDIFF_NORMED give positive values. The method TM_CCOEFF_NORMED easily returns negative values. This is because T'(x',y') and also I'(...) is defined as a difference between two values: [Definition of T' and I'](https://i.stack.imgur.com/nNvyH.png) The answer of Jeru Luke Jun 21 '18 at 8:23 is right. – feli_x Mar 05 '19 at 10:08
  • @feli_x thx for remind and the definition link. I just accepted the answer. – G_cy Mar 06 '19 at 01:51

1 Answers1

1

This problem occurs because both the images are of the same size.

I tried out the same approach but using different image sizes. I used to following images:

Image 1: (125 x 108 pixels) Image

enter image description here

Image 2: (48 x 48 pixels) Template

enter image description here

When I ran the given code for these images it returned an array containing values where each value corresponds to how much the region (of Image) around a certain pixel matches with the template (Template).

Now when you execute cv2.minMaxLoc(templ_match) it returns 4 values:

  1. minimum value: pixel the matches the least in the image when compared with template
  2. maximum value: pixel the matches the most in the image when compared with template
  3. minimum_location: position of occurrence of minimum value
  4. maximum_location: position of occurrence of maximum value

This is what I got:

Out[32]: (-0.15977318584918976, 1.0, (40, 12), (37, 32))
                    ^            ^       ^         ^
                    |            |       |         |
                min_val       max_val  min_loc   max_loc  

This result is observed when the image and template are of different sizes. In your case you have resized all the images to the same size as a result you are only getting a single value which is the first value of templ_match. Moreover you must avoid doing templ_match = cv2.matchTemplate(im1g, im3g, cv2.TM_CCOEFF_NORMED)[0][0]

But rather perform templ_match = cv2.matchTemplate(im1g, im3g, cv2.TM_CCOEFF_NORMED) and then obtain the maximum and minimum value along with their locations using : cv2.minMaxLoc(templ_match)

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • If the problem caused by the small size icon, does it means I need to resize my icons to different sizes. cuz in really project all icons given will be same size. And what does the negative min_val means in you result? One more, can I know the reason why we must avoid doing that way? this actually comes from this answer: https://stackoverflow.com/a/45485883/3330229 – G_cy Jun 21 '18 at 07:08
  • When you perform this for images having the same size the min_val and max_val will be the same like this `(0.5552718639373779, 0.5552718639373779, (0, 0), (0, 0))`. `min_val` means the value that is least similar (or highly different) when compared to the other image. – Jeru Luke Jun 21 '18 at 07:26
  • Could I consider the problem won't happen always for same size pics? After I just try to resize pics to 32*32, the return value seems not go negative. – G_cy Jun 21 '18 at 07:42
  • You can consider same size images but they will return just one value. If the images are nearly similar/same it will be close to 1. But if the images are different they will be near 0. Images somewhat similar will have some value between 0 and 1. – Jeru Luke Jun 21 '18 at 07:47
  • I always thought that the return value of this function should between 0 and 1, which is from doc link above. As a newbie in cv, I am so confused by the negative value generate by this function. I sincerely hope to know how to explain or understand this situation here. Does it simply caused by the same size of two input images? Sry for repetition and thx for your patience. – G_cy Jun 21 '18 at 08:06
  • @G_cy I think only methods `cv2.TM_SQDIFF` and `cv2.TM_SQDIFF_NORMED` return values between 0 and 1. Other methods return values between -1 and 1 including `cv2.TM_CCOEFF_NORMED`. – Jeru Luke Jun 21 '18 at 08:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173541/discussion-between-jeru-luke-and-g-cy). – Jeru Luke Jun 21 '18 at 09:34
  • I know it quite a long time, sry for late. Currently, I borrow some idea from popular deep learning implements. I tried to get feature vector from pretrain inception model, meanwhile I also wrote a simple autoencoder to do the same thing in other way. It shows that it's ok to use feature vector/matrix to find similar images(proper distance function is needed for matrix), but it worked not well enough for my task. In our scenario. When we see blue F, it's FB. When it become FB of blue(or other color), we will also consider it highly likely to be FB. This beyond image features. – G_cy Jul 08 '19 at 02:43
  • So it far more than extract image feature. Do u have any idea of this kind of thing. – G_cy Jul 08 '19 at 02:47