How compare pixels from two images to find a match?

I am having two images where second image is the warped image of previous one. Using random generator , I am selecting 8x8 pixels to compare both images and find the match(minimization function).
I am getting an error in fminunc
Error using fminunc (line 171)
FMINUNC requires the following inputs to be of data type double: 'X0'.
Error in mainsample (line 14)
[s fval] = fminunc(@myfun , subblock)
How do I go about it?
My code for generating random pixels are:
clear all;
close all;
I = rgb2gray(imread('testimage.jpg'));
original = rgb2gray(imread('testimage.jpg'));
original = double(original);
for( j = 0 : 1:7)
r = randi(225-7);
c = randi(225-7);
subblock = I(r:r+7, c:c+7);
imshow(subblock);figure;
t = [1 1];
[s fval] = fminunc(@myfun , subblock)
end
function f = myfun(x)
scale = 0.7;
J = imresize(x, scale);
theta = 30;
x0 = imrotate(J,theta);
for( i = 1:1:225)
f = (x^2 - x0(i)^2);
end

Answers (4)

2 Comments

Hey! Thank you for your reply! I am getting an error with the above mentioned function, which I'm unable to debug
You did not share the solution

Sign in to comment.

Your algorithm of checking randomly selected patches for similarity seems destined to fail. You'd be better off using normxcorr2() to find where one patch occurs in the other image, like in my attached demo.
To compare images in general, use psnr() or immse() or ssim().

12 Comments

Dear Image Analyst,
I have a similair problem and I also tried your demo but the reason is not what I am looking.
Consider I have series of images captured from a video. Lets consider a video is 60 seconds and I extract 60 images from it. In these images, scenes are always changing but there is text in lower part of the images which is fixed for 30 images and changed from image number 31.
I am trying to find the image where the text is changed.
You can consider the problem as if I am trying to make blocks of changes. For example if text changes 3 time during 60 second I can detect these changes.
I`ll be happy if you can help me.
Best,
Examine that part of the video and identify which pixels are not changing from frame to frame. Then make them into a mask. Then for each frame, extract pixels from that mask and determine when something has changed. Fairly robust. To make it more robust also check for which pixels have the color of the computer graphics that were used in the first 30 frames and will presumably be used in subsequent frames and make a mask for that in the bounding box of the text of your first 30 frames.
Thank you for your answer.
Let me ask the question in another way.
Lets consider I have ten rgb or gray scale images with different scenes (I have chance to convert RGB to GRAY images). In first 5 images, logo A is shown on the images and for the rest of images logo changed to B.
No matter what the logo is, I am looking for a code which show me this change.
I think the concept is essentially the same : look for pixels in the image that do not substantially change from frame to frame. This assumes the logo is not semi-transparent.
My question is exactly how to look for pixels in the image that do not substantially change from frame to frame.
The logos are not semi-transparent by the way.
I attached two sample images with different logos which may be helpful.
I am using the following code but the result is not satisfactory for now.
NOT: A and B images are attached.
*******************************************************************************************
A = imread('AA.jpg'); A = rgb2gray(A);
B = imread('BB.jpg'); B = rgb2gray(B);
[W,L] = size(A); R = zeros(W,L); Z = 0;
for i = 1:W
for j = 1:L
% if isequal(A(i,j),B(i,j))
if (A(i,j) - B(i,j)) == 0
R(i,j) = R(i,j) + 1;
else
Z = Z + 1;
end
end
end
It looks like those logos are white, so just check if the pixel is white (255,255,255)
if A(i,j,:) = [255:255:255]
Plus you need to do this:
[rows, columns, numberOfColorChannels] = size(A);
since you switched W and L and didn't take the number of color channels so your L is really columns * numberOfColorChannels.
Thanks. With just some minor changes it works.
How to find the score of template matching?
@Arati GawadeThe value of the cross correlation image at any point is a measure of how well the template agrees with the underlying image at that point.
Ok... actually I want to print the output by using if else statement and based on value of template matching as a condition. Is this right approach ?
You could do that, though for an image, if there are lots of places where the template is close in appearance to the main figure, you're going to have many, many things printed, perhaps thousands. But if you want that, then ok.

Sign in to comment.

You can check the difference using Euclidian distance.
test_img = imread('image1.bmp');
input_im = imread('image2.bmp');
minimum =1000;
[row, col] = size(test_img(:,:,1));
distance = zeros(row, col);
for xAxis = 1 : row
for yAxis = 1 : col
distance(xAxis, yAxis) = sqrt((input_im(xAxis, 1) - test_img(yAxis, 1)).^ 2 + (input_im(xAxis, 2) - test_img(yAxis, 2)).^ 2);
end
end
if distance < minimum
minimum = distance;
end

1 Comment

First of all, you made the common beginner mistake of swapping x and y with row and column. The first index of the image arrays is not the x coordinate. It's the y coordinate and it's deceptive to call the y coordinate of input_img "xAxis". If the image is not square and the number of rows is more than the number of columns, your code will throw an error. Like I said, it's a common mistake, so be careful about that.
Secondly the computation doesn't make sense. You're taking the "distance" between the delta of the first columns and the delta of the second columns. Not only doesn't that make sense, but it ignores all columns from 3 onwards.
Third, using minimum, which goes from a scalar to a 2-D array, is unneeded and never even used.
And finally the whole loop thing could be vectorized into a single line of code.

Sign in to comment.

Change
for( i = 1:1:225)
f = (x^2 - x0(i)^2);
end
to
f = 0;
for( i = 1:1:225)
f = f + (x(i).^2 - x0(i).^2);
end
Or, better yet, do not loop and instead
f = sum(x(:).^2 - x0(:).^2);

Asked:

on 21 Oct 2014

Commented:

on 28 Apr 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!