2

I want to compare two images using Python, but I'm not familiar with this language.

I have two images of the same size. I have to create an array containing the pixel-by-pixel difference of the two images. Finally, I have to calculate the average of the sum of all the values ​​of the array, as a float.

I am able to do it using Processing, but I can't do it using Python.

If the two images are the same the result will obviously be 0.

I would like to translate this code into Python (the most important thing is the value of the final average).

PImage img,img2;
int threshold = 64;

void setup(){
    //size(600,400);
    img = loadImage(args[0]);
    img2 = loadImage(args[1]);
    println(comparison(img,img2));
    exit();
}

PImage binarization(PImage img,int threshold){
    for(int i = 0; i < img.pixels.length; i++){
        if(green(img1.pixels[i]) > threshold) img.pixels[i] = color(255);
        else img.pixels[i] = color(0);
    }
    return img;
}

float comparison(PImage img, PImage img2){

    img.filter(GRAY);
    img2.filter(GRAY);

    img = binarazation(img,threshold);
    img2 = binarization(img2,threshold); 

    int array[] = new int[img.pixels.length];

    for(int i = 0; i < img.pixels.length; i++){
        array[i] = int( abs(green(img.pixels[i]) - green(img2.pixels[i])));
    }

    float average = 0;

        for(int i = 0; i < img.pixels.length; i++){
            average+= array[i];
    }
    average = average/img.pixels.length;

    return average;
}

EDIT::::

Thank you very much!

The comparison function that I posted previously is not really correct

it should actually appear an image (after it has been transformed to grayscale) with another image (which canny algorithm has been applied)

how could i modify the comparison function posted by elgordorafiki?

the canny algorithm to use is this:

import cv2
import numpy as np
from matplotlib import pyplot as plt

 

img = cv2.imread ('img', 0)
edges = cv2.Canny (img, 100,110)

plt.subplot (2,1,1), plt.imshow (img, cmap = 'gray')
plt.title ('Original Image'), plt.xticks ([]), plt.yticks ([])
plt.subplot (2,1,2), plt.imshow (edges, cmap = 'gray')
plt.title ('Canny Edge Detection'), plt.xticks ([]), plt.yticks ([])

plt.show ()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Peppe
  • 21
  • 3
  • Which language is that? – Sid Oct 30 '19 at 08:59
  • `If the two images are equal I will obviously get 1 as a value` Shouldn't you be getting 0? The difference of each pixel would be 0, so sum and it's average should also be 0. – Nikhil Wagh Oct 30 '19 at 09:02
  • The code I posted is written in processing I should do the same thing in python – Peppe Oct 30 '19 at 09:02
  • yes, I have corrected the error – Peppe Oct 30 '19 at 09:11
  • You can perform image processing tasks like this in Python 3.x using the [Pillow](https://pypi.org/project/Pillow/) port of the Python Imaging Library (PIL). Here's its [online documentation](https://pillow.readthedocs.io/en/stable/). It will allow you to write Python code to do this. If you have a problem getting it to work, then post another question. – martineau Oct 30 '19 at 09:47
  • Possible duplicate of [python code to compare images in python](https://stackoverflow.com/questions/11816203/python-code-to-compare-images-in-python) – Derte Trdelnik Oct 30 '19 at 10:55
  • Why did you delete the original question and edited it to a completely new one? That is not intended. Ask a question and get an answer. If you've a new question than you've to ask a new question, but not to edit an existing one! – Rabbid76 Oct 30 '19 at 20:09
  • Sorry, is this actually related to the `Processing` language? Because if not: remember to _read tag descriptions_ and don't just pick words that sound relevant ("processing" is **not** a tag for data or image processing in the slightest) – Mike 'Pomax' Kamermans Oct 31 '19 at 16:15
  • @Mike'Pomax'Kamermans Yes it is (was) related to [Processing](https://processing.org/). But the question was edited, so you can't "see" the relation anymore. – Rabbid76 Oct 31 '19 at 17:02

1 Answers1

1

As @martineau suggests, the Python Imaging Library is a good way to go. I personally also think you can use numpy and matplotlib as an alternative. The good thing about python is that you can then use the array and do operation on the whole image instead of using for loops, that would look better and be faster.

As an example I quickly ported your code to python (not sure about what filter is doing there and what value your threshold has, but rest should be pretty much the same)

I have also some doubts (you set to 255 the value after binarizing, that meaning the final average will be somehow high, maybe using values between 1 and 0 would be easier to be interpreted after, but that's up to you).

import numpy as np
import matplotlib.pyplot as plt
import sys

def binarize(img, threshold):

    # create an image with True or False (that can be seen as 1 or 0) and multiply by 255
    binaryimg = (img > threshold).astype(int) * 255
    return binaryimg

def comparison(img1, img2):

    # convert to gray. What's the filter doing?
    gray1 = rgb2gray(img1)
    gray2 = rgb2gray(img2)

    # select a threhsold value and binarize the image
    threshold = 0.5
    gray1_bin = binarize(gray1, threshold)
    gray2_bin = binarize(gray2, threshold)

    # in python you can compute a difference image.
    # so diff will contain in each pixel the difference between the two images
    diff = gray1_bin - gray2_bin

    # the np.mean gives you already sum / number of pixels
    average = np.mean(diff)

    return average

def rgb2gray(col_img):

    # converts images to gray
    weights = np.array([0.3, 0.59, 0.11])
    gray = np.sum([col_img[:, :, i].astype(np.float64) * weights[i] for i in range(3)], axis=0)

    return gray

# the "main" method
if __name__ == "__main__":

    # read the images
    img = plt.imread(sys.argv[1])
    img2 = plt.imread(sys.argv[2])

    result = comparison(img, img2)

    print("The difference between the images is {}".format(result))

Hope this helps!

freerafiki
  • 539
  • 3
  • 10
  • thank you very much!!I would like to ask you one last thing... – Peppe Oct 30 '19 at 10:33
  • ok, now the question is very different! But I don't get what's the problem, the code you posted now it's working! (I tested it). The two threshold (you put 100 and 110) controls the amount of "edges" that you will detect (see [here](https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=canny) for more detailed explanation), play with those values if you need a better results, but otherwise the code is working just fine! – freerafiki Oct 30 '19 at 13:48