I have a list of images that I want to simplify by generating a tile list and indexing the image.
Right now I'm testing with a single image and trying to find out a good alogorithm to compare the tiles. I might have to throw everything out and see if I can do something better. Right now I have this code:
def tileize(img):
tile_list = []
new_img = np.zeros((int(IMGX/TILESIZE),int(IMGY/TILESIZE),0))
i = 0
ri = 0
for r in range(0,img.shape[0],TILESIZE):
cj = 0
for c in range(0,img.shape[1],TILESIZE):
t1 = img[r:r TILESIZE, c:c TILESIZE,:]
new_img[ri,cj] = i
tile = Tile(t1)
tile_list.append(tile)
i =1
cj =1
ri =1
return tile_list,new_img
I then would like to use the tile_list and "shrink" it. I thought to create Tile objects so that I can create a set()
class Tile(object):
def __init__(self, mat):
self.mat = mat
self.hist = cv2.calcHist([mat],[0],None,[256],[0,256])
def __eq__(self, other):
res = cv2.compareHist(self.hist,other.hist,cv2.HISTCMP_CORREL)
if res > 0.95:
return True
return False
def __hash__(self):
return hash(self.hist.flatten())
Which doesn't work because hist is an array.If I just compare the Tile object together (combine) I won't get a shorter list.
What is the best method to reduce the tile_list by comparing its items?
CodePudding user response:
You should not use __eq__
, __hash__
and set
like this since they are not designed for what you are looking for, i.e. approximate equality. One fondamental property of __eq__
and __hash__
is that if two objects are equal then their hash should be equal too. This invariant is not respected in your implementation.
If you have a small number of patches, you could just compare each patch with every other patches and then group them by similarity. Take a look at clustering algorithms for that purpose.
Another option closer to what you already tried is to use Perceptual Hashing algorithms. Take a look at the ImageHash Python library and the examples. The example from find_similar_images.py
seems close to your application.