T O P I C R E V I E W |
pierrotsc |
Posted - Mar 06 2014 : 14:41:40 I hope it is not a dumb question. I have an image that i split into r,G and B channels. I use that code: Blue := Frm_Buffer.ImageEnVect.Proc.GetRGBChannel(0); Green := Frm_Buffer.ImageEnVect.Proc.GetRGBChannel(1); Red := Frm_Buffer.ImageEnVect.Proc.GetRGBChannel(2);
Now if i modify a channel, how can my RGB composite image be updated with the modification I just made to one channel. For example, I made it lighter.
How can I recombine the 3 layers? Thanks. Pierre |
18 L A T E S T R E P L I E S (Newest First) |
spetric |
Posted - Mar 10 2014 : 03:04:37 Actually, I don't see too much reasons to separate RGB channels in order to adjust brightness, as this can be accomplished using:
ImageEnView1.IEBitmap.ChannelOffset[0] := Brightness1.Position; ImageEnView1.IEBitmap.ChannelOffset[1] := Brightness1.Position; ImageEnView1.IEBitmap.ChannelOffset[2] := Brightness1.Position;
as William has stated. However, if blue, red and green are TIEBitmap maps and if they are converted to single channel maps (PixelFormat = ie8g), then you can recombine them using code I've posted, or using ImageEn pixel access properties:
// 1. original 24-bit image is in View1 // 2. channels were separeted using ienProc->GetRGBChannel(n); // 3. our channels images are bmpBlue, bmpRed, bmpGreen. // 4. all channels images were converted to ie8g // (ex. bmpBlue->PixelFormat = ie8g) // 5. recombination of images into View2 follows
TIEBitmap *composite = new TIEBitmap(); composite->PixelFormat = ie24RGB; composite->Width = View1->IEBitmap->Width; composite->Height = View1->IEBitmap->Height; TImageEnProc *ienProc = new TImageEnProc(this); ienProc->AttachedIEBitmap = View1->IEBitmap; TRGB rgb; int i, j; for (j = 0; j < View1->IEBitmap->Width; j++) { for (i = 0; i < View1->IEBitmap->Height; i++) { rgb.b = bmpBlue->Pixels_ie8[j][i]; rgb.g = bmpGreen->Pixels_ie8[j][i]; rgb.r = bmpRed->Pixels_ie8[j][i]; composite->Pixels_ie24RGB[j][i] = rgb; } } View2->IEBitmap->AssignImage(composite); View2->Update(); delete composite; delete ienProc;
Note: accessing pixels in this way (get/set) is time consuming.
|
pierrotsc |
Posted - Mar 09 2014 : 10:44:58 Thank you very much bill and spetric...i will look into the demo and will apply it to my code. Sincerely, Pierre |
w2m |
Posted - Mar 09 2014 : 07:58:53 Pierre:
I managed to be able to separate the RGB color channels and add the color channel to a layer, allow changing the brightness of any selected color channel (layer), combine the RGB layers (color channel) into a composite RGB image, and save the changes to a new file.
There is a new demo called RGB Color Channels here: http://www.imageen.com/ieforum/topic.asp?whichpage=1&TOPIC_ID=1446#5326 It includes the source.
When you separate the color channels they are grayscale, but they can be adjusted to show the color by processing each color channel layer with an ielOR operation, then by subtracting the other two color channels with IntensityRGBAll.
{ Process the layer with a ielOR operation }
ImageEnView1.Layers[iLayer].Operation := ielOR;
{ Subtract the red and blue channels leaving the green channel }
ImageEnView1.Proc.IntensityRGBall(-255, 0, -255); Many thanks to Spetric for his contribution which got me on the right track.
You will notice that after you get the RGB channels, the image looks just like a regular image, except each layer holds a red, green or blue color channel. This is because when the layers are aligned, all three channels are used to display the pixels, so even though there is a Blue, Green and Red layer the image appears as a composite RGB image on the screen. This is because when the layers are aligned (all the pixels are aligned), all three channels are used to display the pixels, so even though there is a Blue, Green and Red layer, the image appears as a composite RGB image on the screen. This is similar to how a CRT monitor or TV displays full color images by using each of its red, blue and green electron guns. If you select a layer and move it around you can see how the image changes. Finally, when you combine the channels, the layers are positioned over each other (Realigned) then the layers are merged back into one bitmap. If you want to realign the layers back to position 0,0 without combining the color channels, select the Align button.
Once you see it in operation and read the comments in the source code you will understand what is going on.
I can not seem to do this when working with the grayscale layers; however. None of the standard ImageEn brightness methods will work with a Red, Green, or Blue layer (Color channel) because the layer only contains one channel out of the three channels necessary for those functions.
William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html Custom ImageEn Development |
pierrotsc |
Posted - Mar 09 2014 : 07:02:39 Bill, to tell you the truth, i have not coded this part yet. i know that my beta tester uses photoshop and change the brightness and contrast of each channel. So i am trying to code that to replicate the same behavior. For example, he may select the eyes on a red channel and give them a different contrast.
I still do not understand how from 3 grayscale layers that have no colors, you are able to reconstruct the whole rgb image. I think maybe photoshop is showing a grayscale layer but in memory it has the color channel associated with it. So when i am modifying the gray image on the display, i am really modifying the color channel in memory. Pierre |
w2m |
Posted - Mar 09 2014 : 06:27:42 Pierre:
I can not get any brightness method to work on a channel other than: ImageEnView1.IEBitmap.ChannelOffset[0] := Brightness1.Position; ImageEnView1.IEBitmap.ChannelOffset[1] := Brightness1.Position; ImageEnView1.IEBitmap.ChannelOffset[2] := Brightness1.Position;
How did you accomplish this?
William Miller |
pierrotsc |
Posted - Mar 09 2014 : 06:08:13 i have not decided yet if i use the same code as the displayadjust demo or the command: procedure AdjustBrightnessContrastSaturation(Brightness, Contrast, Saturation:integer);
i also like the way to change the contrast of a selected region like: ImageEnView1.Proc.Contrast(50);
not sure which one is best at this point. Does it matter what command i use? Thanks. Pierre |
w2m |
Posted - Mar 08 2014 : 21:29:49 Pierre,
Post the code you use to change black and white point, brightness and contrast.
William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html Custom ImageEn Development |
pierrotsc |
Posted - Mar 08 2014 : 20:08:03 just checked your post..going to bed right now.. the main thing that i do to modify a channel is to adjust the black and white point of each channel or change contrast or brightness of a certain channel. that is it..
i will look and try to implement the code tomorrow...changing time right now.. Thank you very much. Pierre |
w2m |
Posted - Mar 08 2014 : 18:33:56 Pierre... Your initial question was "How do I create an RGB composite image after I modify a channel?" You have to work with the real color channels... Red, Green and Blue before you combine the channels or the image will be grayscale and not color. I suppose if you only want to display the grayscale images until the channels are combined, you could copy the layers to another hidden ImageEnView and create the RGB composite image using the RGB colored images in it.
Here is an update for creating the RGB channels in a way that can be merged back into one composite RGB image from the Red, Green and Blue channels:
procedure TForm1.GetRGBChannels1Click(Sender: TObject);
{ Get the image's red, green and blue channels and add them to a layer
and add to ImageEnMView. }
var
iLayer: integer;
iImage: integer;
ieBitmapRed: TIEBitmap;
ieBitmapGreen: TIEBitmap;
ieBitmapBlue: TIEBitmap;
begin
{ Create a TIEBitmap to hold the red channel }
ieBitmapRed := TIEBitmap.Create;
try
{ Create a TIEBitmap to hold the green channel }
ieBitmapGreen := TIEBitmap.Create;
try
{ Create a TIEBitmap to hold the blue channel }
ieBitmapBlue := TIEBitmap.Create;
try
{ ieBitmapRGB has the color image }
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapRGB;
{ Get the Blue channel }
ieBitmapBlue := ImageEnView1.Proc.GetRGBChannel(0);
{ Get the Green channel }
ieBitmapGreen := ImageEnView1.Proc.GetRGBChannel(1);
{ Get the Red channel }
ieBitmapRed := ImageEnView1.Proc.GetRGBChannel(2);
{ Layer 0 has the blue channel ieBitmap }
iLayer := 0;
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapBlue;
{ Process the layer with a ielNormal operation }
ImageEnView1.Layers[iLayer].Operation := ielNormal;
{ Subtract the red and green channels leaving the blue channel }
ImageEnView1.Proc.IntensityRGBall(-255, -255, 0);
{ Assign the blue bitmap to layer 0 }
ImageEnView1.Layers[iLayer].Bitmap.Assign(ieBitmapBlue);
{ Add a blue bitmap to ImageEnMView }
iImage := ImageEnMView1.AppendImage;
ImageEnMView1.SetIEBitmap(iImage, ieBitmapBlue);
{ Layer 1 has the Green channel ieBitmap }
iLayer := ImageEnView1.LayersAdd;
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapGreen;
{ Process the layer with a ielOR operation }
ImageEnView1.Layers[iLayer].Operation := ielOR;
{ Subtract the red and blue channels leaving the green channel }
ImageEnView1.Proc.IntensityRGBall(-255, 0, -255);
{ Assign the green bitmap to layer 0 }
ImageEnView1.Layers[iLayer].Bitmap.Assign(ieBitmapGreen);
{ Add a green bitmap to ImageEnMView }
iImage := ImageEnMView1.AppendImage;
ImageEnMView1.SetIEBitmap(iImage, ieBitmapGreen);
{ Layer 2 has Red channel ieBitmap }
iLayer := ImageEnView1.LayersAdd;
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapRed;
{ Process the layer with a ielOR operation }
ImageEnView1.Layers[iLayer].Operation := ielOR;
{ Subtract the green and blue channels leaving the red channel }
ImageEnView1.Proc.IntensityRGBall(0, -255, -255);
{ Assign the red bitmap to layer 0 }
ImageEnView1.Layers[iLayer].Bitmap.Assign(ieBitmapRed);
{ Add a red bitmap to ImageEnMView }
iImage := ImageEnMView1.AppendImage;
ImageEnMView1.SetIEBitmap(iImage, ieBitmapRed);
finally
ieBitmapBlue.Free;
end;
finally
ieBitmapGreen.Free;
end;
finally
ieBitmapRed.Free;
end;
end; I can probably post the demo tomorrow when I finish testing it. Pierre... show me the code you are using to modify a channel...
William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html Custom ImageEn Development |
w2m |
Posted - Mar 08 2014 : 18:03:48 Ok... I have it working. Very interesting... when you place each channel in a layer, the resulting unmerged layers look like the regular RGB image. When you merge the layers it looks the same... perfect. When I get the demo finished I'll post the result.
William Miller |
pierrotsc |
Posted - Mar 08 2014 : 17:55:21 Awesome..Let me try to implement that..Trying to find some bugs right now. I need to get away from the computer to see clearly. Pierre
Hold on..Just reread your message. I do not want to convert the image to color. Like in photoshop, the channels are in gray but when you modify one, it also modify the RGB image.
Let me think more about that. Pierre |
w2m |
Posted - Mar 08 2014 : 17:23:33 Pierre... I figured out how to convert the RGB images to color based on the comments by spetric.
procedure TForm1.GetRGBChannels1Click(Sender: TObject);
var
iLayer: integer;
ieBitmapRed: TIEBitmap;
ieBitmapGreen: TIEBitmap;
ieBitmapBlue: TIEBitmap;
begin
ieBitmapRed := TIEBitmap.Create;
ieBitmapGreen := TIEBitmap.Create;
ieBitmapBlue := TIEBitmap.Create;
{ Layer 0 has the RGB color image }
ImageEnView1.Proc.AttachedIEBitmap := ImageEnView1.layers[0].Bitmap;
ieBitmapBlue := ImageEnView1.Proc.GetRGBChannel(0);
ieBitmapGreen := ImageEnView1.Proc.GetRGBChannel(1);
ieBitmapRed := ImageEnView1.Proc.GetRGBChannel(2);
{ Layer 1 has the blue channel image }
iLayer := ImageEnView1.LayersAdd;
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapBlue;
ImageEnView1.Proc.IntensityRGBall(-255,-255,0);
ImageEnView1.layers[iLayer].Bitmap.Assign(ieBitmapBlue);
{ Layer 2 has the red channel image }
iLayer := ImageEnView1.LayersAdd;
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapGreen;
ImageEnView1.Proc.IntensityRGBall(-255,0,-255);
ImageEnView1.layers[iLayer].Bitmap.Assign(ieBitmapGreen);
{ Layer 3 has the green channel image }
iLayer := ImageEnView1.LayersAdd;
ImageEnView1.Proc.AttachedIEBitmap := ieBitmapGreen;
ImageEnView1.Proc.IntensityRGBall(0,-255,-255);
ImageEnView1.layers[iLayer].Bitmap.Assign(ieBitmapRed);
ieBitmapBlue.Free;
ieBitmapGreen.Free;
ieBitmapRed.Free;
end; This is a work in progress so I do not have the demo finished yet. Right now I have the full RGB image in Layer 0 so I have to store it somewhere else so I can do a merge.
Thanks Spetric!
William Miller |
pierrotsc |
Posted - Mar 08 2014 : 17:09:27 very nice image..i am impressed. wish i shot it :) i do not think it is going to work for me then from what i can tell. my rgb layers are in grayscale. they are not in color or maybe i misunderstood something. Pierre |
spetric |
Posted - Mar 08 2014 : 17:03:11 I did not do it the same way, but I think that, let's say "Blue" IEBitmap is still 24 bit, but with all channels equal.
If not, image can be converted to 24-bit with all channels equal (resulting again in grayscale image). I've actually "killed" the channels (B and G on the first one, etc..). It can be done by Proc.IntensityRGBall(0,-255,-255), etc...
Result is the same. |
w2m |
Posted - Mar 08 2014 : 16:57:10 When you get the RGB color images with ImageEn they are all gray scale and do not look like the images you show. Blue := ImageEnView.Proc.GetRGBChannel(0); Green := ImageEnView.Proc.GetRGBChannel(1); Red := ImageEnView.Proc.GetRGBChannel(2);
Because the RGBChannel bitmaps are grayscale I would think the merged imges would also be grayscale.
How did you get the RGB images in color?
Maybe you can post your demo here: http://www.imageen.com/ieforum/topic.asp?TOPIC_ID=1446
If you can not post it, send the demo to me and I'll post it for you.
William Miller |
spetric |
Posted - Mar 08 2014 : 16:45:37 I'll try to write in Pascal. Use Operation property for layers 1 and 2 to set it to OR blending mode (Layer[0] is set to ielNormal by defaul):
Viewer.Layers[1].Operation := ielOR; Viewer.Layers[2].Operation := ielOR;
And then, merge all layers into single image:
Viewer.LayersMergeAll();
As you have previously nullified channels OR operation will actually recreate color image.
I've made and axample. I've created 3 layers with same image and then "killed" channels: BG on layer0, RB on 1 and RG on 2.
Example1: channel images in normal blending (blue channel image overlaps all other layers as it's the last one).
Example2: belending modes of layer 1 and 2 are set to OR, original picture is recreated.
LayersMergeAll() will actually create single layer with full color image.
NOTE: All layers are 24 bit images! |
pierrotsc |
Posted - Mar 08 2014 : 16:12:53 Thank you very much..Let me see if i can find out on how to translate that to Delphi (Pascal). I never programmed (Or really little) in C++.
I may post another message if i need some help. I do have the 3 layers. Now I know how to merge all 3 layers using the merge command. Not sure if i understand your statement though: ... and then merge all layers, setting layers 1 and 2 in OR mode.
Let me look at your code, that may give me the answer i am looking for. Sincerely, Pierre |
spetric |
Posted - Mar 08 2014 : 14:40:30 I do such kind of tasks using image byte pointers (I can post code in c++ if you wish), but it can be done by putting your BGR images in layers 0, 1, 2, nullifying unnecessary channels and merging all layers in one image with OR blending.
To nullify, let's say red and green channels use Proc.IntensityRGBall(-255,-255,0)
So, let's say your blue image is in layer 0, green in layer 1 and red in layer 2, then the order would be:
Proc.AttachedIEBitmap = layer[0].TIEBitmap Proc.IntensityRGBall(-255,-255,0) Proc.AttachedIEBitmap = layer[1].TIEBitmap Proc.IntensityRGBall(-255,0,-255) Proc.AttachedIEBitmap = layer[2].TIEBitmap Proc.IntensityRGBall(0,-255,-255)
... and then merge all layers, setting layers 1 and 2 in OR mode. Maybe there is a simpler solution, but I don't know it. The fastest one is to perform bytes modification through complete image.
Edit: I have attached a c++ code with low-level byte manipulation, regarding this case.
./attach/spetric/201438144529_composite.zip |
|
|