How to convert a Grey Scale image to RGB in C#? - c#

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

Related

How to show a YCbCr image using Emgu in C#?

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

How to convert true type font to bitmap image?

I have a difficulty as I am trying to render a character with a specific font style to the bitmap image (black and white). My question is the font is basically black and white and I am writing the character in black (against white background), however when I convert it to bitmap image I get a coloured thin outline around the bindery of my character.
Can anyone tell me where that grey color comes from while I am writing it with black color and how can i get ONLY black and white pixels?
The pixels that aren't completely black or completely white are the result of anti-aliasing. Anti-aliasing is used by default since everyone who doesn't know about it probably wants it.
I suggest two alternatives. One, create your bitmap with a one bit per pixel format, which will not give anti-aliasing a chance. Second, you can go through the resulting image after the text has been drawn pixel by pixel and adjust each pixel to either black or white based on a threshold. I.e. if the picture is darker than half then it's black, otherwise it's white. e.g. if (red+green+blue > 383) set_pixel_white() else set_pixel_black(); But you'll need be ready for some rather funny results. You may need to play with the thresholds.
PS there's a better solution, you can tweak anti-aliasing. MSDN You'll set your rendering to System.Drawing.Text.TextRenderingHint.SingleBitPerPixel or something that suits you.

Color spaces conversions

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.

Change background colour of an anti-aliased image using C# with anti-aliasing

I have an image where I need to change the background colour (E.g. changing the background of the example image below to blue).
However, the image is anti-aliased so I cannot simply do a replace of the background colour with a different colour.
One way I have tried is creating a second image that is just the background and changing the colour of that and merging the two images into one, however this does not work as the border between the two images is fuzzy.
Is there any way to do this, or some other way to achieve this that I have no considered?
Example image
Just using GDI+
Image image = Image.FromFile("cloud.png");
Bitmap bmp = new Bitmap(image.Width, image.Height);
using (Graphics g = Graphics.FromImage(bmp)) {
g.Clear(Color.SkyBlue);
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.None;
g.DrawImage(image, Point.Empty);
}
resulted in:
Abstractly
Each pixel in your image is a (R, G, B) vector, where each component is in the range [0, 1]. You want a transform, T, that will convert all of the pixels in your image to a new (R', G', B') under the following constraints:
black should stay black
T(0, 0, 0) = (0, 0, 0)
white should become your chosen color C*
T(1, 1, 1) = C*
A straightforward way to do this is to choose the following transform T:
T(c) = C* .* c (where .* denotes element-wise multiplication)
This is just standard image multiplication.
Concretely
If you're not worried about performance, you can use the (very slow) methods GetPixel and SetPixel on your Bitmap to apply this transform for each pixel in it. If it's not clear how to do this, just say so in a comment and I'll add a detailed explanation for that part.
Comparison
Compare this to the method presented by LarsTech. The method presented here is on the top; the method presented by LarsTech is on the bottom. Notice the undesirable edge effects on the bottom icon (white haze on the edges).
And here is the image difference of the two:
Afterthought
If your source image has a transparent (i.e. transparent-white) background and black foreground (as in your example), then you can simply make your transform T(a, r, g, b) = (a, 0, 0, 0) then draw your image on top of whatever background color you want, as LarsTech suggested.
If it is a uniform colour you want to replace you could convert this to an alpha. I wouldn't like to code it myself!
You could use GIMP's Color To Alpha source code (It's GPL), here's a version of it
P.S. Not sure how to get the latest.
Background removal /replacement, IMO is more art than science, you’ll not find one algorithm fit all solution for this BUT depending on how desperate or interested you are in solving this problem, you may want to consider the following explanation:
Let’s assume you have a color image.
Use your choice of decoding mechanism and generate a gray scale / luminosity image of your color image.
Plot a graph (metaphorically speaking) of numeric value of the pixel(x) vs number of pixels in the image for that value(y). Aka. a luminosity histogram.
Now if your background is large enough (or small), you’d see a part of the graph representing the distribution of a range of pixels which constitute your background. You may want to select a slightly wider range to handle the anti-aliasing (based on a fixed offset that you define if you are dealing with similar images) and call it the luminosity range for your background.
It would make your life easier if you know at least one pixel (sample/median pixel value) out of the range of pixels which defines your background, that way you can ‘look up’ the part of the graph which defines your background.
Once you have the range of luminosity pixels for the background, you may run through the original image pixels, compare their luminosity values with the range you have, if it falls within, replace the pixel in the original image with the desired color, preferably luminosity shifted based on the original pixel and the sample pixel, so that the replaced background looks anti-aliased too.
This is not a perfect solution and there are a lot of scenarios where it might fail / partially fail, but again it would work for the sample image that you had attached with your question.
Also there are a lot of performance improvement opportunities, including GPGPU etc.
Another possible solution would be to use some of the pre-built third party image processing libraries, there are a few open source such as Camellia but I am not sure of what features are provided and how sophisticated they are.

changing hue and saturation in pixel level

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.

Categories

Resources