python2.7 histogram comparison - white background anomaly - python

my program's purpose is to take 2 images and decide how similar they are.
im not talking here about identical, but similarity. for example, if i take 2 screenshots of 2 different pages of the same website, their theme colors would probably be very similar and therefor i want the program to declare that they are similar.
my problem starts when both images have a white background that pretty much takes over the histogram calculation (over then 30% of the image is white and the rest is distributed).
in that case, the cv2.compareHist (using correlation method, which works for the other cases) gives very bad results, that is, the grade is very high even though they look very different.
i have thought about taking the white (255) off the histogram before comparing, but that requires me to calculate the histogram with 256 bins, which is not good when i want to check similarity (i thought that using 32 or 64 bins would be best)
unfortunately i cant add images im working with due to legal reasons
if anyone can help with an idea, or code that solves it i would be very grateful
thank you very much

You can remove the white color, rebin the histogra and then compare:
Compute a histrogram with 256 bins.
Remove the white bin (or make it zero).
Regroup the bins to have 64 bins by adding the values of 4 consecutive bins.
Perform the compareHist().
This would work for any "predominant color". To generalize, you can do the following:
Compare full histrograms. If they are different, then finish.
If they are similar, look for the predominant color (with a 256-bin histogram), and perform the procedure described above, to remove the predominant color from the comparisson.

Related

Comparing fluorescence intensity of finger print residue after 5 contacts

I have an image as follows that shows the residue of fluorescent powder left on a surface after 5 sequential contacts. Is it possible to quantify the a difference in the amount of residue between contacts?
I have looked at Fiji/ImageJ and selected each finger print at a time to get the mean grey value but I don't see much difference to be honest. Any help or thoughts would be very much appreciated. Happy to think about python or matlab.
In order for the quantification of the intensities to be useful, I would imagine you would need to assume your image was evenly lit and that any fluorescence you see isn't a result of oversaturation. That being said, in principle, you could contour the given fingerprint, duplicate it to a new image, and then measure the stack histogram after adjusting the threshold such that regions darker than your fingerprint powder are set to black. Perhaps the change in distribution will illustrate the change that occurs, if any.
Edit:
First: merge the RGB channels by adding them to one another using the channel calculator function. Your signal is the result of multiple colors, so splitting it does not make sense to me here.
The steps would then be:
Duplicate your given print to a new window.
Use "Adjust Threshold" to set a threshold of 0-n, where n is the highest intensity that doesn't include your fingerprint.
Run the command "Edit/Selection/Create Selection."
Run the command "Edit/Clear."
Press "ctrl+H" to measure the histogram of the pixels, and then "List" to get the actual values.
Repeat for each print and plot on the same chart.
When you are already obtaining the actual histogram values, and not just the range from the particle analyzer, then I'm not sure there's much else that I can personally suggest.

Creating string art from image

I am relatively new to python. I would like to make some string-art portraits. I was watching this video which really intrigued me:
https://youtu.be/RSRNZaq30W0?t=56
I understand that to achieve this, I would first need to load the image, then do some edge-detection and then use some form of Delaunay triangulation but have no idea where to even start.
I looked up some sample code for OpenCV and figured out how to do basic edge-detection. How do I then convert those to points? And then what sort of algorithm would I need to "fill in" the different gradients?
I don't even know if this is the right approach to achieve this. Could someone please point me in the right direction and perhaps give me some sample code to get started? I would really appreciate it very much.
Edge detection or triangulation is less important in this application. The core part is to understand the pseudo-code at 1:27 of the video. The final product uses a single string at wrap around different nails in particular way, so that: darker areas in original image have less string density, and brighter areas have more strings crossing over.
The initial preparation is to:
generate an edge dection version of the image (A)
generate a blurred version of the image (B)
Then the first step is to create random positions for the nails. Apparently to achieve a good outcome, if a random-generated nail is close enough to the 'edge' of a black-white image, you should 'snap' it to the edge, so that later the strings wrapping around these edge nails will create an accurate boundary just like in the original picture. Here you use the image A) to adjust your nails. For example, just perform some potential minimization:
Add small random position change to the nails. If a nail now gets
close enough to a white point (edge) in image A), directly change to
that position.
Compute the potential. Make sure your potential function
penalizes two points that come too close. Repeat 1) 100 times to
pick one with lowest potential.
Iterate 1) and 2) 20 times
Next you decide how you want the strings to wrap around the nails.
Starting from a point A, look at some neighboring points (within certain radius) B1, B2, B3, etc. Imagine if you attach a string with certain width from A to Bi, it visually changes your string image P in a slight way. Render line segment A-B1 on P to get P1, render A-B2 on P to get P2, etc.
Find the best Bi so that the new image Pi looks closer to the original. You can just do a pixel-wise comparison between the string image and the original picture, and use this measurement to score each Bi. The video author used a blurred image B) to get rid of textures that may randomly impact his scoring algorithm.
Now the optimal Bi becomes the new A. Find its neighbors and loop over. The algorithm may stop if adding any new strings only negatively impacts the score.
There are cases where bright areas in a photo are widely separated, so any white strings crossing the dark gap will only decrease the score. Use your judgement to tweak the algorithm to workaround those non-convex scenarios.

What are the advantages / disadvantages between the different predefined ArUco dictionaries?

I want to use ArUco markers to detect objects and use a predefined dictionary.
I only need a small amount of different markers. About 10. I am now wondering what the advantages and disadvantages are between the different predefined dictionaries.
Dictionaries differ in amount of markers and bit size.
My thoughts so far:
Having a lower amount of markers decreases the inter marker
distance, thus the chance of faulty marker ID classification. However, the maximum amount of available unique markers is lower.
Having a lower bit size helps to identify the markers better if
their pixel size in the captured image is small (marker are printed small / far away in image). However, the maximum amount of available unique markers is lower.
Is my thought process so far correct? Did I miss anything?
So for me, only needing 10 different markers, I probably should stick to the DICT_4X4_50 dictionary to achieve best marker detection results?!
Or would it even be better to create my own dictionary with even less markers to increase inter marker distance?
I am the main ArUco developer. I personally recommend the first 10 markers of the ARUCO_MIP_36h12 dictionary. Unless you are working at an extremely low resolution, there is no real improvement in working with small markers such as 4x4 or 3x3. This is because internally the library reduces the detected marker to a small size (of around 50x50 bits regardless its dimensions in the actual image) and it is in this resolution in which the code is analyzed.
The fully explained pipeline of the ArUco library is described in the latest paper
https://www.researchgate.net/publication/325787310_Speeded_Up_Detection_of_Squared_Fiducial_Markers in Sect 3.2. Also, you can have more information in the documentation at
https://docs.google.com/document/d/1QU9KoBtjSM2kF6ITOjQ76xqL7H0TEtXriJX5kwi9Kgc
Complementing Rafael's answer, on the bit size, with the relevant quote in the docs:
Markers are comprised by an external black border and an inner region that encodes a binary pattern. The binary pattern is unique an identifies each marker. Depending on the dictionary, there are markers with more or fewer bits. The more bits, the more words in the dictionary, and the smaller the chance of a confusion. However, more bits means that more resolution is required for correct detection.

How to identify stripes of different colors

how can I identify the presence or absence of regular stripes of different colors, but ranging from very very very very light pink to black inside of a scanned image (bitmap 200x200dpi 24-bit).
Carry a few examples.
Example 1
Example 2 (the lines are in all the columns except 7 in the second row of the last column)
For now try to identify (using python language) whether or not there is at least 5-10 pixels for the presence of different color from white to each strip, however, does not always work because the scanned image is not of high quality and the strip changes color very similar to color that surrounds it.
Thanks.
This looks to me a connected component labeling in an image to identify discrete regions of certain color range. You can have a look to cvBlobLib. Some pre-processing would be required to merge the pixels if there are holes or small variations between neighbors.
Not going to happen. The human visual system is far better than any image processing system, and I don't see anything in the 2nd row of #3. #1 and #5 are also debatable.
You need to find some way to increase the optical quality of your input.
Search for segmentation algorithm ,with a low threshold.
It should give you good results as the edges are sharp.
Sobel would be a good start ;)

Detecting Similar images [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Image comparison algorithm
So basically i need to write a program that checks whether 2 images are the same or not. Consider the following 2 images:
http://i221.photobucket.com/albums/dd298/ramdeen32/starry_night.jpg
http://i221.photobucket.com/albums/dd298/ramdeen32/starry_night2.jpg
Well they are both the same images but how do i check to see if these images are the same. I am only limited to the media functions. All i can think of right now is the width height scaling and compare the RGB for each pixel but wouldnt the color be different?
Im completely lost on this one, any help is appreciated.
*Note this has to be in python and use the (media library)
Wow - that is a massive question, and one that has a vast number of possible solutions. I'm afraid I'm not a python expert, but I thought your question was interesting - so I wanted to propose a method that I would implement if I were posed with this problem.
Obviously, the two images you posted are actually very different - so you will need to consider 'how much different is the same', especially when working with images and considering different image formats and compression etc.
Anyway, for a solution that allows for a given difference in colour values (but not for pixels to be in the wrong places), I would do something like the following;
Pick two images.
Rescale the largest image to the exact same height and width as the first (even distorting the image if necessary).
Possibly grayscale the images to make the next steps simpler, without losing much in the way of effectiveness. Actually, possibly running edge detection here could work too.
Go through each pixel in both images and store the difference in either each of the RGB channels, or just the difference in grayscale intensity. You would end up with an array the size of the image noting the difference between the pixel intensities on the two images.
Now, I don't know the exact values, but you would probably then find that if you iterate over the array you could see whether the difference between each pixel in the two images is the same (or nearly the same) across all of the pixels. Perhaps iterate over the array once to find the average difference between the pixel intensities in the two images, then iterate over the image again to see if 90% of the differences fall within a certain threshold (5% difference?).
Just an idea. Of course, there might be some nice functions that I'm not aware of to make this easy, but I wouldn't hold my breath!
ImageMagick has Python bindings and a comparison function. It should do most of the work for you, but I've never used it in Python.
I think step 2 of John Wordsworths answer may be one of the hardest - here you are dealing with a stretched copy of the image but do you also allow rotated, cropped or in other ways distorted images? If so you are going to need a feature matching algorithm, such as used in Hugin or other panorama creation software. This will find matching features, distort to fit and then you can do the other stages of comparing. Ideally you want to recognise Van Gogh's painting from photos, even photos on mugs! It's easy for a human to do this, for a computer it needs rather more complex maths.

Categories

Resources