How to treshold image from greyscale screen by webcome - opencv

I have image like this from my windstation
I have tried get thoose lines recognized, but lost becuase all filters not recognize lines.
Any ideas what i have use to get it black&white with at least some needed lines?
Typical detection result is something like this:
I need detect edges of digit, which seams not recognized with almost any settings.

This doesn't provide you with a complete guide as to how to solve your image processing question with opencv but it contains some hints and observations that may help you get there. My weapon of choice is ImageMagick, which is installed on most Linux distros and is available for OS X and Windows.
Firstly, I note you have date and time across the top and you haven't cropped correctly at the lower right hand side - these extraneous pixels will affect contrast stretches, so I crop them off.
Secondly, I separate your image in 3 channels - R, G and B and look at them all. The R and B channels are very noisy, so I would probably go with the Green channel. Alternatively, the Lightness channel is pretty reasonable if you go to HSL mode and discard the Hue and Saturation.
convert display.jpg -separate channel.jpg
Red
Green
Blue
Now make a histogram to look at the tonal distribution:
convert display.jpg -crop 500x300+0+80 -colorspace hsl -separate -delete 0,1 -format %c histogram:png:ahistogram.png
Now I can see all your data are down the dark, left-hand end of the histogram, so I do a contrast stretch and a median filter to remove the noise
convert display.jpg -crop 500x300+0+80 -colorspace hsl -separate -delete 0,1 -median 9x9 -normalize -level 0%,40% z.jpg
And a final threshold to get black and white...
convert display.jpg -crop 500x300+0+80 -colorspace hsl -separate -delete 0,1 -median 9x9 -normalize -level 0%,40% -threshold 60% z.jpg
Of course, you can diddle around with the numbers and levels, but there may be a couple of ideas in there that you can develop... in OpenCV or ImageMagick.

Related

imagemagick check if image is of almost one single color

Friends,
I have a stack of color-scanned images. Some are from regular white paper with text or images, others were scanned from colored paper (blank pages, same green colored paper used.)
I'd like to identify these colored paper images. Problems:
paper's color ("background") is not scanned very uniformly, often has a wavy or structured pattern
green tone is quite different depending on the scanner used
scanner does not catch the full sheet resulting in a white or shadowed "border" around green area
My idea was to see if say 90% of the image is some sort of green and tried using a sorted histogram. But because of (1) and esp. (2) I have a hard time picking a working color value from the histogram data.
Any help appreciated!
Edit:
Here are three sample images, scanned from the same sheet of paper.
Have a look at HSV colourspace on Wikipedia - specifically this diagram.
It should be a better place to find the colour of your images, regardless of scanner and calibration.
Now, let's create a lime-green, yellow and cyan block and derive its colour using ImageMagick:
magick -size 100x100 xc:lime -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
120
magick -size 100x100 xc:yellow -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
60
magick -size 100x100 xc:magenta -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
300
magick -size 100x100 xc:cyan -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
180
Hopefully you can see we are correctly calculating the Hue angle. Now to your image. I have added an artificial frame so you can see how to remove the edges:
We can remove the frame like this:
magick YOURSCAN.jpg -gravity center -crop 80% cropped.jpg
So, my complete suggestion would be to crop and convert to HSV and check the mean Hue. You could also test if the image is fairly saturated so it doesn't pick up grey-ish, uncoloured images. You could also test the variance in the Hue channel to see if there are many different colours - or the spread of the hues is large and reject ones where it is large.
magick YOURSCAN.jpg -gravity center -crop 80% -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
Just for reference, your 3 images come up with the following Hue angles on a scale of 0..360:
79, 68, 73
I would suggest you test a few more samples to establish a reasonable range.

ImageMagick: Divide AE distortion by total pixels in fx output info format

I am trying to use ImageMagick 7 to detect if a specific channel in an image is largely pure black and pure white (plus a little antialiasing, and there's a chance the image could be pure black). This is to distinguish from another kind of image that shares a naming convention but has photographic-like image data in the r/g/b channels.
(Basically both image types are specular maps from different engines. The one I'm trying to differentiate here is more modern and has the metallic map in the blue channel; the other is much older and just has the specular colour in the RGB channels and the gloss map in the alpha.)
Currently I'm comparing the channel to a clone of itself that has had a 50% threshold applied, using the AE metric to see if it's largely the same apart from a small amount of antialiasing, and a fuzz of 1% to account for occasional aberration from pure black/white. This command works, but of course at the moment it only returns the number of distorted pixels:
magick ( "file.png" -channel b -separate ) ^
( +clone -channel b -separate -threshold 50% ) ^
-fuzz 1% -metric AE -compare ^
-format "%[distortion]" info:
Because the input image sizes will vary, I want to divide the distortion by the total number of pixels in the image to get the relative amount of the image that's not pure black/white -- under 10% has seemed good so far in my manual testing -- but I can't get the format syntax right. Everything I've tried -- for example "%[fx:%[distortion]/w*h]" -- has given the magick: undefined variable `[distortion]' # error/fx.c/FxGetSymbol/1169 error.
What syntax should I use? (And if there's a better way to do what I'm doing, I always appreciate it!)
I believe the following is what you want in Imagemagick. Basically you save the distortion in -set option: argument and then use it in -fx later.
However, +clone gives you just the b channel, so there should be no need for -channel b -separate in your second line.
magick ( "file.png" -channel b -separate ) ^
( +clone -threshold 50% ) ^
-fuzz 1% -metric AE -compare ^
-set option:distort "%[distortion]" ^
-format "%[fx:distort/(w*h)]" info:
Fred (#fmw42) has already provided an excellent method. There is another method for differentiating pure black and white images from greyscale images with a fuller tonal scale which may interest you. Credit to Anthony Thyssen for the technique described here.
If you use -solarize 50% in ImageMagick it inverts all the highlights, so it effectively folds your histogram in half and all the whites become pure black and all the near-whites become near blacks. The command looks like this:
magick INPUT -solarize 50% OUTPUT
So, if I apply that to a couple of input images - the first one pure black and near white, the second a greyscale - and show the corresponding output image on the right you'll see the effect:
If you now inspect the mean and standard deviation of the two solarised images:
magick {a,b}-sol.jpg -format "%f, mean: %[mean], stdev: %[standard-deviation]\n" info:
a-sol.jpg, mean: 2328.91, stdev: 3175.67
b-sol.jpg, mean: 16319.5, stdev: 9496.04
you can see that the mean and standard deviation of the first (pure black and white) image is low because all the bright whites have folded to near blacks, whereas the mean and standard deviation of the greyscale image are both higher because the tones are more spread out.

Compare pixels moved but similar images using ImageMagick

When comparing two images, both of the images are the same, except that in one of the images the text is moved by a couple of pixels. Please take a look at the below URL. It is a GIF that shows the difference of both the similar images.
https://giphy.com/gifs/9x50JjoLSPZ7lKRebk
My team initially used compare command which doesn't address this issue. Need suggestions please?
You can remove all the text in Imagemagick and just compare the bars by thresholding the Saturation/Chroma channel and then doing the compare. The text is gray, so it has little if any saturation. The bars are cyan, so they are colored and have a medium to high saturation.
convert giphy.gif -colorspace HCL -channel g -separate +channel -threshold 5% +write tmp.gif miff:- | compare -metric rmse - null:
3164.96 (0.0482942)
So this is 4.8% different.
I save tmp.gif, which you do not need, only to show the result of the processing before the compare.
If your version of Imagemagick is too old and you do not have -colorspace HCL, then try HSL or HSB. C and S are similar and measure saturation/chroma.

Changing exposure of jpeg

Given a jpeg, what is the formula to change the exposure of that jpeg by +/-1 stop or as known as 1 EV? I want to simulate this exposure change. Is there a formula/ method to do so?
I can demonstrate that using ImageMagick, which is included in most Linux distros and available for OSX and Windows from here.
First, at the Terminal command line create an image:
convert -size 512x512 gradient:black-yellow gradient.png
Now, the way to effect +1 stop exposure increase is to composite the image with itself using the Screen blending mode - it is available in Photoshop and ImageMagick and is described here.
So, the formula to composite image A with image B is:
1-stop brighter image = 1-(1-A)(1-B)
but as we are compositing the image with itself, A and B are the same, so we effectively have
1-(1-A)(1-A)
ImageMagick refers to the pixels of an image using p rather than A, so we can do a 1-stop increase like this:
convert gradient.png -colorspace RGB -fx "(1-(1-p)(1-p))" result.png
Note that the Wikipedia article, and ImageMagick's -fx both assume your pixel intensities vary between 0 and 1.0. If you are using 8-bit images, you should calculate with 255 in place of 1, namely
+1 stop brighter image = 255-(255-A)(255-A)
or if using 16-bit values
+1 stop brighter image = 65535-(65535-A)(65535-A)
The above fx-based method is however, very slow because the -fx is interpreted rather than compiled, so a faster way to do it is:
convert gradient.png gradient.png -colorspace RGB -compose screen -composite screen.png
Just for fun, another way of looking at that is that we take the inverse of A, that is 1-A, and square it, and then take the inverse, so it can be done like this:
convert gradient.png -colorspace RGB -negate -evaluate pow 2 -negate result.png
The equivalent of -1 stop exposure decrease is to composite the image with itself using the Multiply blend mode, the formula being
1-stop darker image = A x B
which you would do faster with
convert gradient.png gradient.png -colorspace RGB -compose multiply -composite result.png
or even faster, by using memory-to-memory cloning rather than reading from disk twice, with
convert gradient.png -colorspace RGB +clone -compose multiply -composite result.png
but could do equally with
convert gradient.png -colorspace RGB -evaluate pow 2 result.png

ImageMagick: Promote grays to CMYK black?

Is there a way to move all gray colors of a CMYK image (e.g. a CMYK .tiff) into the black (K) plate with ImageMagick?
(In Adobe Acrobat Pro, this functionality is labeled: "Promote grays to CMYK black")
Here's an image to experiment with:
You can view an example of this process on Wikipedia.
Also not a full answer as such, but hopefully useful towards producing one - by Kurt, myself or others. I looked at the Photoshop method of GCR and am adding the characteristic curves that Adobe seem to use for GCR. There are 5 levels, ranging from "None", through "Light", "Medium", "Heavy" and "Full".
I presume the "Light" curve is showing that no black ink is added into the mix till it would be over 50%, and the "Medium" shows the black would have to be only 25% before any gets added, and the "Heavy" shows that only 12-15% of black is needed before black ink gets added into the mixture.
I also add the following reference to assist any other answerers... see PDF here.
Taking into account that the provided example image is NOT a TIFF (as announced), and does NOT use a CMYK color space (as announced), but is a JPEG using sRGB, here is how you would convert it into a TIFF file using CMYK, where the black channel is used:
convert \
http://i.stack.imgur.com/HFnCz.jpg \
-colorspace cmy \
-colorspace cmyk \
cmyk.tiff
To separate out the different colors again and show them as grayscale images each, use these commands:
convert HFnCz.tiff -colorspace cmyk -channel c -separate channel_c.png
convert HFnCz.tiff -colorspace cmyk -channel m -separate channel_m.png
convert HFnCz.tiff -colorspace cmyk -channel y -separate channel_y.png
convert HFnCz.tiff -colorspace cmyk -channel k -negate -separate channel_k.png
I did output to PNG in order to keep the file size a bit smaller...
Here are the 4 color separations. Top left is C, top right is M, bottom left is Y, bottom right is K:
Update
I made a mistake in my original answer. The -negate command parameter should only be there for the blacK channel.

Resources