Plutonergy

Compare two images

Apr 6th, 2021
645
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.71 KB | None | 0 0
  1.  
  2. class ImageComparer(object):
  3.     def __init__(self, image_one, image_two):
  4.  
  5.         if os.path.exists('/mnt/ramdisk'):
  6.             self.tmp_folder = '/mnt/ramdisk'
  7.         else:
  8.             self.tmp_folder = tempfile.gettempdir()
  9.  
  10.         self.work = {}
  11.         self.work.update({'original_one': {'path': image_one}})
  12.         self.work.update({'original_two': {'path': image_two}})
  13.  
  14.         self.delete_us = []
  15.  
  16.     def reload_image_as(self, load_type, **kwargs):
  17.         """
  18.        reuses self.work by reseting it back to "starting" state
  19.        if 'move' in kwargs, before popping each key they're stored into self.work['move']
  20.        :param load_type: 'rgb', 'gray'
  21.        :param kwargs: str move
  22.        """
  23.         self.type = load_type
  24.  
  25.         all_keys = []
  26.         for string,_ in self.work.items():
  27.             all_keys.append(string)
  28.  
  29.         for string in all_keys:
  30.             if string != 'original_one' and string != 'original_two':
  31.                 if string != 'rgb' and string != 'gray':
  32.                     if 'move' in kwargs:
  33.                         if kwargs['move'] not in self.work:
  34.                             self.work.update({kwargs['move']: {}})
  35.  
  36.                         self.work[kwargs['move']].update({string: self.work[string]})
  37.  
  38.                     self.work.pop(string)
  39.  
  40.         if 'only_move' not in kwargs:
  41.             if self.type == 'rgb':
  42.                 self.work['original_one']['image'] = Image.open(self.work['original_one']['path'])
  43.                 self.work['original_two']['image'] = Image.open(self.work['original_two']['path'])
  44.  
  45.             elif self.type == 'gray':
  46.                 self.work['original_one']['image'] = Image.open(self.work['original_one']['path']).convert('LA')
  47.                 self.work['original_two']['image'] = Image.open(self.work['original_two']['path']).convert('LA')
  48.  
  49.             self.delete_us.append(self.work['original_one']['image'])
  50.             self.delete_us.append(self.work['original_two']['image'])
  51.  
  52.     def make_slices(self, **kwargs):
  53.         """
  54.        takes self.work['resized_one/two']['image'] and slices them up in 12 slices
  55.        if highjacked, data of interest is in self.work['slices'][count]['rgb_image']
  56.        :param kwargs['no_slice'] == makes 12 slices, but all are the same/entire image
  57.        """
  58.         if 'resized_one' not in self.work or 'resized_two' not in self.work:
  59.             self.make_images_same_size(**kwargs)
  60.  
  61.         if 'slices' not in self.work:
  62.             self.work.update({'slices': {}})
  63.         else:
  64.             return
  65.  
  66.         loads = [self.work['resized_one']['image'], self.work['resized_two']['image']]
  67.         for c in range(len(loads)):
  68.  
  69.             if c not in self.work['slices']:
  70.                 self.work['slices'].update({c: {}})
  71.  
  72.             image = loads[c]
  73.             im_width = image.size[0]
  74.             im_height = image.size[1]
  75.  
  76.             left = 0
  77.             top = 0
  78.             right = (im_width / 3) - 1
  79.             bottom = (im_height / 4) - 1
  80.  
  81.             for cc in range(12):
  82.  
  83.                 if cc not in self.work['slices'][c]:
  84.                     self.work['slices'][c].update({cc: {}})
  85.  
  86.                 if cc > 0:
  87.                     if right + (im_width / 3) - 1 > im_width:
  88.                         left = 0
  89.                         top += (im_height / 4) - 1
  90.                         right = (im_width / 3) - 1
  91.                         bottom += (im_height / 4) - 1
  92.                     else:
  93.                         left += (im_width / 3) - 1
  94.                         right += (im_width / 3) - 1
  95.  
  96.                 if 'no_slice' in kwargs:
  97.                     cropped_image = image
  98.                 else:
  99.                     cropped_image = image.crop((left,top,right,bottom))
  100.                     self.delete_us.append(cropped_image)
  101.  
  102.                 self.work['slices'][c][cc].update({'image': cropped_image})
  103.  
  104.  
  105.     def make_images_same_size(self, **kwargs):
  106.         """
  107.        takes the smallest of the images and make both of them that size
  108.        if highjacked you're interested in self.work['resized_one/two']['image'] & ['path']
  109.        """
  110.         im1 = self.work['original_one']['image']
  111.         im2 = self.work['original_two']['image']
  112.  
  113.         if im1.size[0] * im1.size[1] > im2.size[0] * im2.size[1]:
  114.             size = im2.size[0], im2.size[1]
  115.         else:
  116.             size = im1.size[0], im1.size[1]
  117.  
  118.         self.work.update({'resized_one': {'image': im1.resize(size=size, resample=Image.LANCZOS)}})
  119.         self.work.update({'resized_two': {'image': im2.resize(size=size, resample=Image.LANCZOS)}})
  120.  
  121.         self.work['resized_one'].update({'path': self.tmp_folder + '/resized_one.webp'})
  122.         self.work['resized_two'].update({'path': self.tmp_folder + '/resized_two.webp'})
  123.  
  124.         self.work['resized_one']['image'].save(self.work['resized_one']['path'], 'webp', quality=50, optimize=False)
  125.         self.work['resized_two']['image'].save(self.work['resized_two']['path'], 'webp', quality=50, optimize=False)
  126.  
  127.         self.delete_us.append(self.work['resized_one']['image'])
  128.         self.delete_us.append(self.work['resized_two']['image'])
  129.  
  130.     def fast_fill_values(self, **kwargs):
  131.         """
  132.        injects self.work['slices'][count][count]['colors']
  133.        injects self.work['slices'][count][count]['len_colors']
  134.        injects self.work['slices'][count][count]['histogram']
  135.        injects self.work['slices'][count][count]['entropy']
  136.        """
  137.         self.make_slices(**kwargs)
  138.  
  139.         cdef list all_histogram = []
  140.         cdef list all_entropy = []
  141.         cdef list all_len_colors = []
  142.         cdef list hist_diff, slicelist, listofvalues, shrink
  143.  
  144.         cdef dict cd
  145.  
  146.         cdef float final_slice_percent, each_percent, add_values
  147.         cdef float one_size, two_size
  148.  
  149.         cdef int c, cc, ccc, cccc
  150.         cdef int maxcolors, tmp_hist
  151.  
  152.         cdef str stringkey
  153.  
  154.         for c in range(2):
  155.             for cc in range(len(self.work['slices'][c])):
  156.                 slice = self.work['slices'][c][cc]
  157.                 if 'colors' not in slice:
  158.                     maxcolors = 16800
  159.                     colors = slice['image'].getcolors(maxcolors=16800)
  160.                     while colors == None:
  161.                         maxcolors = maxcolors * 2
  162.                         colors = slice['image'].getcolors(maxcolors=maxcolors)
  163.                         if maxcolors > 10000000000:
  164.                             break
  165.  
  166.                     slice.update({'colors': colors})
  167.                     slice.update({'len_colors': len(colors)})
  168.                 if 'histogram' not in slice:
  169.                     histogram = slice['image'].histogram()
  170.                     slice.update({'histogram': histogram})
  171.                 if 'entropy' not in slice:
  172.                     entropy = slice['image'].entropy()
  173.                     slice.update({'entropy': entropy})
  174.  
  175.  
  176.         for c in range(1):
  177.             for cc in range(len(self.work['slices'][c])):
  178.                 slicelist = [self.work['slices'][0][cc], self.work['slices'][1][cc]]
  179.                 shrink_count = len(slice['histogram']) / 32
  180.  
  181.                 for slice in slicelist:
  182.                     shrink = []
  183.  
  184.                     while slice['histogram'] != []:
  185.                         tmp_hist = 0
  186.  
  187.                         for ccc in range(int(shrink_count)):
  188.                             if slice['histogram'] == []:
  189.                                 break
  190.                             tmp_hist += slice['histogram'][-1]
  191.                             slice['histogram'].pop(-1)
  192.  
  193.                         shrink.append(tmp_hist)
  194.  
  195.                     slice['histogram'] = shrink
  196.  
  197.                 hist_diff = []
  198.  
  199.                 for ccc in range(len(slicelist[0]['histogram'])):
  200.                     try:
  201.                         if slicelist[0]['histogram'][ccc] < slicelist[1]['histogram'][ccc]:
  202.                             hist_diff.append(slicelist[0]['histogram'][ccc] / slicelist[1]['histogram'][ccc])
  203.                         elif slicelist[0]['histogram'][ccc] > slicelist[1]['histogram'][ccc]:
  204.                             hist_diff.append(slicelist[1]['histogram'][ccc] / slicelist[0]['histogram'][ccc])
  205.                         else:
  206.                             hist_diff.append(1)
  207.                     except IndexError:
  208.                         pass
  209.  
  210.                 final_slice_percent = 0.0
  211.                 for each_percent in hist_diff:
  212.                     final_slice_percent += each_percent
  213.  
  214.                 all_histogram.append(final_slice_percent / len(hist_diff))
  215.                 for cccc in range(2):
  216.                     slicelist[cccc].update({'history_percent_off': round(final_slice_percent/len(hist_diff), 2)})
  217.  
  218.         cd = {
  219.             'entropy_percent_off': ('entropy', all_entropy),
  220.             'len_colors_percent_off': ('len_colors', all_len_colors),
  221.         }
  222.  
  223.         for c in range(1):
  224.             for cc in range(len(self.work['slices'][c])):
  225.                 slicelist = [self.work['slices'][0][cc], self.work['slices'][1][cc]]
  226.  
  227.                 for stringkey, guidetuple in cd.items():
  228.  
  229.                     key = guidetuple[0]
  230.                     if slicelist[0][key] < slicelist[1][key]:
  231.                         guidetuple[1].append(slicelist[0][key] / slicelist[1][key])
  232.                         for ccc in range(2):
  233.                             slicelist[ccc].update({stringkey: round(slicelist[0][key] / slicelist[1][key], 2)})
  234.                     elif slicelist[0][key] > slicelist[1][key]:
  235.                         guidetuple[1].append(slicelist[1][key] / slicelist[0][key])
  236.                         for ccc in range(2):
  237.                             slicelist[ccc].update({stringkey: round(slicelist[1][key] / slicelist[0][key], 2)})
  238.                     else:
  239.                         for ccc in range(2):
  240.                             slicelist[ccc].update({stringkey: 1.0})
  241.  
  242.         one_size = os.path.getsize(self.work['resized_one']['path'])
  243.         two_size = os.path.getsize(self.work['resized_two']['path'])
  244.  
  245.         if one_size < two_size:
  246.             self.work.update({'size_percent_off': round(one_size / two_size, 2)})
  247.         else:
  248.             self.work.update({'size_percent_off': round(two_size / one_size, 2)})
  249.  
  250.         cd = {
  251.             'entropy_percent_off': all_entropy,
  252.             'history_percent_off': all_histogram,
  253.             'len_colors_percent_off': all_len_colors,
  254.         }
  255.  
  256.         for stringkey, listofvalues in cd.items():
  257.             add_values = 0
  258.             for value in listofvalues:
  259.                 add_values += value
  260.  
  261.             if add_values > 0:
  262.                 self.work.update({stringkey: round(add_values / len(listofvalues), 2)})
  263.             else:
  264.                 self.work.update({stringkey: 1})
Advertisement
Add Comment
Please, Sign In to add comment