Comparing 2 images pixel by pixel (the first image is stored at a database) - c++

I want to compare 2 images, where the first image is stored in a database and the second image is from a live video stream via a webcam. Is it possible to determine whether there are some differences between the images, or whether they are identical?
I want the image comparison to be pixel by pixel. If a pixel by pixel comparison is hard, or even impossible, could you suggest a better way of doing this?

A simple pixel by pixel comparison is unlikely to work well because of noise in the webcam image.
You need a similarity measure like Peak signal-to-noise ratio (PSNR) or Structural Similarity (SSIM)

Perform a hash function on your image and compare it with the precalculated image hash in the database.

Related

How to get the corresponding pixel color of disparity map coordinate

I'm currently working on an assignment, consisting of camera calibration, stereo-calibration and finally stereo matching. For this I am allowed to use the available OpenCV samples and tutorials and adapt them to our needs.
While the first two parts weren't much of a problem, a Question about the stereo matching part:
We should create a colored point cloud in .ply format from the disparity map of two provided images.
I'm using this code as a template:
https://github.com/opencv/opencv/blob/master/samples/cpp/stereo_match.cpp
I get the intrinsic and extrinsic files from the first two parts of the assignment.
My question is, how to get the corresponding color for each 3D-point from the original images and the disparity map?
I'm guessing that each coordinate of the disparity map corresponds to a pixel both input-images share. But how to get those pixelvalues?
EDIT: I know that the value of each element of the disparity map represents the disparity the corresponding pixel between the left and right image. But how do I get the corresponding pixels from the coordinates of the disparity map?
Example:
my disparity value at coordinates (x, y) is 128. 128 represents the depth. But how do I know which pixel in the original left or right image this corresponds to?
Additional Questions
I'm having further questions about StereoSGBM and which parameters make sense.
Here are my (downscaled for upload) input-images:
left:
right
Which give me these rectified images:
left
right
From this I get this disparity image:
For the disparity image: this is the best result I could achieve using blocksize=3 and numDisparities=512. However I'm not at all sure if those parameters make any sense. Are these values sensible?
My question is, how to get the corresponding color for each 3D-point from the original images and the disparity map?
So a disparity map is nothing but distance between matching pixels in the epipolar plane in the left and right images. This means, you just need the pixel intensity to compute the disparity which in turn implies, you could do this computation on either just the grey-scale left-right image or any of the channels of the left-right images.
I am pretty sure the disparity image you are computing operates on grey-scale images obtained from the original rgb images. If you want to compute a color disparity image, you just need to extract the individual color channels of the left-right images, and compute the corresponding disparity map channel. The outcome will then be a 3 channel disparity map.
Additional Questions I'm having further questions about StereoSGBM and which parameters make sense. Here are my (downscaled for upload) input-images:
There is never a good answer to this for the most general case. You need a parameter tuner for this. See https://github.com/guimeira/stereo-tuner as an example. You should be able to write your own in open cv pretty easily if you want.
Ok the solution to this problem is to use the projectpoint() function from OpenCV.
Basically calculate 3D-Points from the disparity image and project them onto the 2D image and use the color you hit.

Applying normalization to RGB images and getting RGB images as output

My question is very short and very naïve but I found very different answers on Internet. What is the most effective (and actually used in the Computer Vision community) way of normalizing an RGB image.
This question comes from the fact that algorithm like PCA or even contrast normalization are described often in their 2D-versions.
Therefore for whitening/global contrast normalization or whatever methods you like to preprocess images to feed to a statistical method of your liking: do you consider each channel separately or do you reshape the depth-3 thing into a rectangular 2D-array (of depth-1) (and how to do that while preserving structure) do your thing and then split it back to its former shape ?
I think each method has its advantages considering the image as a whole seems more meaningful but applying to each channel separately is more simple.
There is no simple answer to your question.
For most tasks it is sufficient to operate on separate RGB or HSI channels. Most images in image processing are gray scale anyway so most algorithms expect gray scale input.
In most scenarios pre-processing serves the sole purpose of reducing information to the necessary minimum. So an RGB output "back in its former shape" with preserved structures does not exist. At least in my world.
If you want RGB output from RGB input you would implement a function that operates on RGB values. Unless you can reduce the calculations to grayscale and already have the necessary grayscale functions implemented.
How can you reshape an image into a 2D array? Usually an image is a 2D array...
I will make my answer specific to ZCA whitening but I guess it is the same for others:
As the input of the PCA has the shape of a 2D-matrix with (nsamplesxfeatures) dimension. I thought of using the RGB channels as nsamples and the image in those channel flattened as features.
The answer seems to be to use nsamples as nsamples (the numbers of images you have if you have several RGB images) and to use the RGB-image completely flattened as features.
This answer leads me to believe that if you want to normalise an image you should use the general mean of the image and general standard deviation and not to consider each channel separately.
If somebody disagrees he is free to comment, I agree that my question was a bit too broad.

OpenCV Histogram to Image Conversion

I've tryout some tutorial of converting Grayscale image to Histogram and thus perform comparision between the histogram. So, I've obtained the value returned from compare function in double datatype. Like this.
My problem here now is, how can I visualize the "non-match/ error" detected between images? Can I like obtained back the coordinates of those non-match pixels and draw a rectangle or circle at that particular coordinate?
Or any suggestion on algorithm I can take?
You can't do that from histogram comparison directly. As stated in the documentation,
Use the function compareHist to get a numerical parameter that express how well two histograms match with each other.
This measure is just a distance value which tells you how similar are the two histograms (or how similar are the two images in terms of color distribution).
However, you can use histogram backprojection to visualize how well each pixel in image A
fits the color distribution (histogram) of an image B. Take a look to that OpenCV example.

correspond values between two images in opencv / c++

I am new in image processing and opencv. I have two images. I want to find correspond values in the image 2 with the image 1. and then show it. is there any function in opencv to find correspond values between images?
thanks in advance.
Mat corrVals;
bitwise_and(image2, image1>0, corrVals);
image1>0 will create temporary binary image with values 0 and 255. Than the only thing you need is to perform AND operation between pixels of your images, and store result somewhere. This is done by bitwise_and.
This is similar to approach suggested by #Mailerdaimon but uses much cheaper operations.
You can threshold you image1 such that all Values you want are 1 and all other are 0.
Than you multiply image1 with image2.
cv::multiply(image1, image2, result, scale, dtype)
This will return an image with all values greater than zero from image2 that are marked in image1.
It is hard to say without looking at your images. This is a well studied problem in computer vision and OpenCV contains several algorithms for this. The problem you're looking at can be very easy or very hard, depending on:
your images, are the normal images? just shapes? binary?
where on the images lie the corresponding pixels
how fast you need this to run
how much variation there is between images, is it exactly the same pixel value?
is there camera movement?
is there variation in illumination?
You can start by looking at stereo matching and optical flow inside OpenCV.

Image comparison method with C++ and OpenCV

I am new to OpenCV. I would like to know if we can compare two images (one of the images made by photoshop i.e source image and the otherone will be taken from the camera) and find if they are same or not.
I tried to compare the images using template matching. It does not work. Can you tell me what are the other procedures which we can use for this kind of comparison?
Comparison of images can be done in different ways depending on which purpose you have in mind:
if you just want to compare whether two images are approximately equal (with a few
luminance differences), but with the same perspective and camera view, you can simply
compute a pixel-to-pixel squared difference, per color band. If the sum of squares over
the two images is smaller than a threshold the images match, otherwise not.
If one image is a black-white variant of the other, conversion of the color images is
needed (see e.g. http://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale). Afterwarts simply perform the step above.
If one image is a subimage of the other, you need to perform registration of the two
images. This means determining the scale, possible rotation and XY-translation that is
necessary to lay the subimage on the larger image (for methods to register images, see:
Pluim, J.P.W., Maintz, J.B.A., Viergever, M.A. , Mutual-information-based registration of
medical images: a survey, IEEE Transactions on Medical Imaging, 2003, Volume 22, Issue 8,
pp. 986 – 1004)
If you have perspective differences, you need an algorithm for deskewing one image to
match the other as well as possible. For ways of doing deskewing look for example in
http://javaanpr.sourceforge.net/anpr.pdf from page 15 and onwards.
Good luck!
You should try SIFT. You apply SIFT to your marker (image saved in memory) and you get some descriptors (points robust to be recognized). Then you can use FAST algorithm with the camera frames in order to find the coprrespondent keypoints of the marker in the camera image.
You have many threads about this topic:
How to get a rectangle around the target object using the features extracted by SIFT in OpenCV
How to search the image for an object with SIFT and OpenCV?
OpenCV - Object matching using SURF descriptors and BruteForceMatcher
Good luck