I am trying to write a program that after the user inputs an image, he could see some small image processing. More specific, I want to convert an image from RGB to CMYK and YUV and then show on screen only one component from those color spaces(i.e. only cyan from CMY or U from YUV).
I managed to implement a conversion, but at the moment I want to create a bitmap with the desired component I get stuck, as I don't know how to do it. Which channel from RGB corresponds to which CMYK/YUV component?Or am I just wrong and there is no correspondence?
Thanks!
There is no direct correspondence between RGB and CMYK or YUV, that said there are clearly conversions. You can choose to manipulate the image in the desired color space before converting it back to RGB for display. So it would be possible to isolate a specific channel in say CMYK, copy that channel to a new image and then convert that to RGB for display.
Related
I'm struggling with finding a optimal binarization as preprocessing step for OCR (tesseract in C#).
The images are 1624 X 1728 of pixel size and contain car gui elements (Buttons, Sliders, Info Boxes) and corresponding text from a car navigation command interface generation (different use case scenarios like radio control, car control, etc.). The images contain multiple colors, most of images are dark blue, and the text is white/gray or close to white. Unfortunately, I cannot share the images due to data privacy.
Problem: I cannot separate the text from the background in a efficent way (text to be black, everything else to be white), because the text color has a high range and is partialy the same with the background color (speaking of grayscaled images).
Actual procedure: First I convert the RGB Image from System.Drawing.Image to OpenCvSharp.Mat. Then I convert the Mat image from colored to gray and then from gray to binarized.
This is the main code for the binarization:
Mat binarized = grayscaled.Threshold(tresh, maxVal, ThresholdTypes.BinaryInv);
I use 255 as maxVal. If I use tresh=90, the binarized image looks ok overall (even if tesseract results are bad here), but some pixels of the bottom control elements text (and some other text) are white, because the tresh is too high (so some text characters are unsharp and not complete).
If I use like tresh = 40, the characters of the bottom control elements become complete and sharp (as the should be), but the background (middle of the image) gets completely black, which means that some text in there disappears inside of a big black chunk.
So the problem is a high text pixel color range inside of the grayscaled image that "interferes" with the colors of other elements or background, which makes the text extraction hard.
Note: I already tried AdaptiveThresholding like MeanC and GaussianC with different treshholds, kernel sizes and mean substraction constants without good results.
Question: What would be a efficient solution for the preprocessing?
I'm thinking about writing a method that binarizas from RGB, not from grayscaled. So the method would take a RGB image as input and binarize that white text color range into black and everything else into white.
One approach is to remove any frequencies in the image lower than that of your text. This can be done by creating a blurred copy of the image, with a kernel a bit larger than your text, and subtract this blurred image from the original. This should keep high frequencies, i.e. text and other edges, while removing any vignetting or other gradients over the image. Keep in mind that the resulting image will have a different range of values, where some will probably be negative.
Another option would be to split the image into sections, and use different thresholds in each, but that may lead to artifacts at the section boundaries.
I got a bitmap as a source;
I created a Emgu image with Image<Bgr,Byte> img = new Image<Bgr,Byte>(bmp);
I converted it to a YCbCr image using Image<Ycc,Byte> YCB = img.Convert<Ycc,Byte>();
I dragged a imagebox from the toolbox and assigned it with YCB -----> imagebox1.Image=YCB;
but the result shows the image in RGB format just like source bitmap
I don't understand where went wrong
Could someone give me some clues?
Have you made any alterations to YCB? If you simply display it then it will look identical to the original.
If you right click on your imagebox when running your program and select property it will tell you the type of image and show you the data held within the YCB image this should be different from your original. Alternatively just show 1 channel of your image matrix so for your BGR show the blue colour this will obviously be displayed as a single colour grayscale image. Now for the YCB show the Luma channel again this will be displayed as a single colour grayscale image. You will notice a slight change between them as the luma represents the luminance of all 3 colour spectrums.
CvInvoke.cvShowImage("Blue", img [0]);
CvInvoke.cvShowImage("Luma", YCB[0]);
If you want to see a greater difference multiply the Luma by 2 and you have a completely different image.
YCB[0] *= 2;
CvInvoke.cvShowImage("Luma Change", YCB);
The CvInvoke.cvShowImage() method is a great tool for debugging your code and seeing what your code is doing to images step by step.
For the benefits of others Ycc is YCbCr colour space: http://en.wikipedia.org/wiki/YCbCr
Cheers,
Chris
Say I have two colors, red and pink. How would I define a relationship between them such that I would be able to use it to get say, light blue from blue? The 'pink' isn't just light red, so I don't want to use ControlPaint.Light. The easiest way I can think of is to get the HSB difference between red and pink and just add that to the base blue color, but c# lacks methods to convert those HSB values back to RGB and I would rather not write my own if I can help it. Is there another way?
If you want to adjust the lightness of a color without changing the hue, your best option is to convert the RGB color to HSL. Then adjust the lightness by a certain amount. Then convert it back to RGB if needed.
You can find a lot of examples of code to use to do the conversion such as the following:
Convert RGB bytes to HSL and back?
How to convert a Grey scale image to RGB format? I have added Aforge library too but unable to define thresholds for coloring.
I'm not understand clearly what do you mean under Convert gray scale image to RGB and suppose that you are trying to revive colors. Unfortunately it's not possible to do it precisely. I mean you can revive colors from grayscale image but this colors would not exactly the colors was befor transforming to gray.
Standard transformation from color to grayscale assumes that every pixel of image transformed by formula:
G(R,G,B) = 0.299*R + 0.587*G + 0.114*B
where R, G and B are RGB values of pixel
As you understand reverse that transformation may have many different results. Look at http://en.wikipedia.org/wiki/Grayscale for more info.
You also may take a look at this project. It implements solution that makes attempt to revitalize colors from grayscale image. But again, take im mind that this colors would not be an original colors
Anton has a good point which is the resulting colored image will not have the colors in the original image.
This is why coloring a grayscale image is called false coloring I believe.
For images with palette, you can just replace the palette.
For images without palettes, you will have to define a formula to work with.
In our application, we used sdk called leadtools that had functions for coloring gray images and we find it to be very helpful.
Using Aforge do this:
var filter = new GrayscaleToRGB();
var RGBBitmap = filter.Apply(AForge.Imaging.Image.Convert16bppTo8bpp(bitmap));
(if you already have a 8bpp bitmap you can leave out the conversion)
GrayscaleToRGB is in AForge.Imaging.Filters
I'm working on a image processing project where i need to change the color of the object. For that i have performed a threshold operation and obtained object pixels as shown in the image. After that i have applied the various colors to object using setPixel method in c#. But this method destroy all the characteristics of the images. But actually i need something like the bottom images. I obtained the them by editing in Adobe Photoshop by changing hue and saturation. can you guys make any suggestions how do this.
code example appreciated, thanks in advance.
Original Image
Threshold Image
Color Applied Image
Required Image
Obtain the hue, saturation, and brightness of every pixel from the RGB values (RGB<->HSV). Then play with them, and convert the image back to RGB.