How compare pixels from two images to find a match?
Show older comments
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)
Stalin Samuel
on 21 Oct 2014
1 vote
2 Comments
Emmanuel
on 21 Oct 2014
Augustine Ekweariri
on 19 Nov 2016
You did not share the solution
Image Analyst
on 20 Nov 2016
1 vote
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
SN MJTHD
on 13 Oct 2019
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,
Image Analyst
on 14 Oct 2019
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.
Image Analyst
on 15 Oct 2019
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.
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
Image Analyst
on 16 Oct 2019
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.
SN MJTHD
on 17 Oct 2019
Thanks. With just some minor changes it works.
Arati Gawade
on 27 Apr 2022
How to find the score of template matching?
Image Analyst
on 27 Apr 2022
@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.
Arati Gawade
on 28 Apr 2022
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 ?
Image Analyst
on 28 Apr 2022
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.
Augustine Ekweariri
on 22 Nov 2016
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
Image Analyst
on 22 Nov 2016
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.
Walter Roberson
on 20 Nov 2016
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);
Categories
Find more on ROI-Based Processing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!