Re: Specific color channel to retrieve from an image in a plugin

Posted by Philippe GENDRE on
URL: http://imagej.273.s1.nabble.com/Specific-color-channel-to-retrieve-from-an-image-in-a-plugin-tp5004950p5005083.html

Thank you Rob.

I have tested the following lines :

int[] colPixels = (int[]) ip.getPixels();
        int PixelCount = ip.getPixelCount();
        byte[] bluePixels=new byte[PixelCount];

             for (int x = 0; x < PixelCount; x++) {

                   int  pixVal = colPixels [x];
                    //get red , green and blue values from pixVal
                       int redVal = (pixVal & 0xff0000) >> 16;
                      int greenVal = (pixVal & 0x00ff00) >> 8;
                    int blueVal = (pixVal & 0x0000ff);

                        if  (blueVal <redVal &&blueVal<greenVal )
                             bluePixels[x]=0;
                        else bluePixels[x]=(byte)blueVal;
             }

        ImageProcessor ipb = new
ByteProcessor(frame_width,frame_height,bluePixels);


It is three times slower than the previous code. I suspect that to cast int
to byte is "slow" then I tested the same code without casting :


int[] colPixels = (int[]) ip.getPixels();
        int PixelCount = ip.getPixelCount();
        int[] bluePixels=new int[PixelCount];

             for (int x = 0; x < PixelCount; x++) {

                   int  pixVal = colPixels [x];
                    //get red , green and blue values from pixVal
                       int redVal = (pixVal & 0xff0000) >> 16;
                      int greenVal = (pixVal & 0x00ff00) >> 8;
                    int blueVal = (pixVal & 0x0000ff);

                        if  (blueVal <redVal &&blueVal<greenVal )
                             bluePixels[x]=0;
                        else bluePixels[x]=blueVal;
             }

        ImageProcessor ipb = new
ColorProcessor(frame_width,frame_height,bluePixels);

The speed is 3 times higher. If this behaviour is normal, I have no special
need to convert  RGB image to byte.

The frames I have to process are not specially big (1 MO) but I need a good
frame rate according to analyze what append in real time (from the camera
live stream).

Best regards,

Philippe



2013/10/8 Rob van 't Hof <[hidden email]>

> Hi Philippe,
>
> You could specify the blueVal array as byte[], and change the line to:
>
> blueVal[x] = (byte)(blueal);
>
> you can then create a byte processor straight from the array.
>
> Also do you really need the redVal and greenVal arrays for later use?
> because assigning these arrays takes time and filling them with the values
> (and reading them in the if statement) takes time. Having local int redval
> and greenval variables would be quite a bit faster. so you would have:
>
>
>                 for (int x = 0; x < PixelCount; x++) {
>
>                    int  pixVal = colPixels [x];
>                     //get red , green and blue values from pixVal
>                    int redval = (pixVal & 0xff0000) >> 16;
>                    int greenval = (pixVal & 0x00ff00) >> 8;
>                    int blueval = (pixVal & 0x0000ff);
>
>                         if  (blueval <redval &&blueval<greenval ){
>                              blueVal[x] =0;
>                         }
>                         else{
>                              blueVal[x] =(byte)(blueval);
>                         }
>
>  If your images are big, you could contemplate multi threading. It's not
> too complicated for something like this. You assign as many chunks of your
> arrays as you have processors in your system, and then run the code in
> parallel. There is a code example how to do this somewhere on the Fiji web
> site. If you're interested I could dig out some of my own code. However,
> I'm moving house and lab at the moment so do not have direct access to all
> my stuff just now.
>
> bye,
> Rob
>
>
>
> On 08/10/2013 10:17, Philippe GENDRE wrote:
>
>> Thanks to Herbie and Rob.
>>
>> Herbie : yes you are right, it is not slow it takes time but what Rob
>> proposes is considerably faster and it is just what I try to do.
>>
>> Rob : I use the following lines :
>>          int[] colPixels = (int[]) ip.getPixels();
>>          int PixelCount = ip.getPixelCount();
>>          int[] redVal=new int[PixelCount];
>>          int[] greenVal=new int[PixelCount];
>>          int[] blueVal=new int[PixelCount];
>>
>>               for (int x = 0; x < PixelCount; x++) {
>>
>>                     int  pixVal = colPixels [x];
>>                      //get red , green and blue values from pixVal
>>                     redVal[x] = (pixVal & 0xff0000) >> 16;
>>                     greenVal[x] = (pixVal & 0x00ff00) >> 8;
>>                     blueVal[x] = (pixVal & 0x0000ff);
>>
>>                          if  (blueVal[x] <redVal[x] &&blueVal[x]
>> <greenVal[x] )
>>                               blueVal[x] =0;
>>               }
>>
>>          ImageProcessor ipB = new
>> ColorProcessor(frame_width,**frame_height,blueVal);
>>
>> In my case, this code is 3 times faster than the previous one.
>> Another request is how to cast blueVal values into a ByteProcessor without
>> consuming time. Adding the line ipB=ipB.convertToByte(false) is time
>> consuming.
>>
>> Best regards,
>>
>> Philippe
>>
>>
>> 2013/10/7 Rob van 't Hof <[hidden email]>
>>
>>  Sorry, just noticed that there is a line  that is not needed: the // get
>>> brightness etc comment. The perils of copy and paste.
>>> Also you can further speed up things using multithreading if you use a
>>> more modern processor with multiple cores. this only gives substantial
>>> benefits if you are using really largish images (mine can be up to 100
>>> Mpixels).
>>> Rob
>>>
>>>
>>> On 07/10/2013 13:15, Rob van 't Hof wrote:
>>>
>>>  Hi,
>>>> getPixelValue is not particularly fast. The fastest way of going through
>>>> an image pixel by pixel is using the 1-dimensional array access methods.
>>>>
>>>> Here is a code snippet:
>>>>
>>>> int[] colPixels = (int[]) ip.getPixels();
>>>> PixelCount = ip.getPixelCount();
>>>>
>>>>       for (int x = 0; x < PixelCount; x++) {
>>>>             //get brightness from shading image
>>>>             int  pixVal = colPixels [x];
>>>>              //get red , green and blue values from pixVal
>>>>             int  redVal = (pixVal & 0xff0000) >> 16;
>>>>             int  greenVal = (pixVal & 0x00ff00) >> 8;
>>>>             int  blueVal = (pixVal & 0x0000ff);
>>>>
>>>>                  if  (blueVal <redVal &&blueVal <greenVal )
>>>>                       blueVal =0;
>>>>                   }
>>>>          }
>>>>
>>>> Hope this helps,
>>>>
>>>> Rob
>>>>
>>>>
>>>>
>>>> On 07/10/2013 11:26, Herbie wrote:
>>>>
>>>>  Philippe,
>>>>>
>>>>> you say you need to inspect every pixel of your image and that this is
>>>>> slow.
>>>>>
>>>>> Sorry, but I don't think it is slow but it simply takes time,
>>>>> especially
>>>>> if your images are big. Don't you agree?
>>>>>
>>>>> If you do the loop over all pixels in Java, I see little chance to
>>>>> speed
>>>>> up the desired process.
>>>>>
>>>>> Best
>>>>>
>>>>> Herbie
>>>>> ______________________________****___________
>>>>>
>>>>> On 07.10.13 10:16, Philippe GENDRE wrote:
>>>>>
>>>>>  Dear List,
>>>>>>
>>>>>> Recently, I posted a question to this list to retrieve a specific
>>>>>> color
>>>>>> channel (the red one for example) from a RGB image. The answer
>>>>>> (ImageProcessor red = ((ColorProcessor)ip).****getChannel(1, null);)
>>>>>> is
>>>>>>
>>>>>> perfect
>>>>>> but I have realized that it is not what I need. In fact I need to
>>>>>> retrieve
>>>>>> a specific color of pixel for example the blue ones and not the
>>>>>> intensity
>>>>>> of the channel. According to that I wrote the following code:
>>>>>> ImageProcessor ipR=((ColorProcessor)ip).****getChannel(1,null);
>>>>>> ImageProcessor ipG=((ColorProcessor)ip).****getChannel(2,null);
>>>>>> ImageProcessor ipB=((ColorProcessor)ip).****getChannel(3,null);
>>>>>>
>>>>>>
>>>>>>       for (int x=0; x<frame_width; x++){
>>>>>>           for (int y=0; y<frame_height; y++){
>>>>>>               if
>>>>>> (ipB.getPixelValue(x,y)<ipR.****getPixelValue(x,y)&&ipB.**
>>>>>> getPixelValue(x,y)<ipG.****getPixelValue(x,y))
>>>>>>
>>>>>>                   ipB.set(x,y,0);
>>>>>>           }
>>>>>>       }
>>>>>> That sounds good but slow. How to speed up this ?
>>>>>>
>>>>>> Best regards,
>>>>>>
>>>>>> Philippe
>>>>>>
>>>>>>
>>>>>> 2013/9/26 Philippe GENDRE <[hidden email]>
>>>>>>
>>>>>>   ImageProcessor red = ((ColorProcessor)ip).****getChannel(1, null)
>>>>>> is
>>>>>>
>>>>>>> exactly
>>>>>>> what I needed.
>>>>>>>
>>>>>>> This list is a marvel. Thanks a lot.
>>>>>>>
>>>>>>> Philippe
>>>>>>>
>>>>>>>
>>>>>>> 2013/9/26 Rasband, Wayne (NIH/NIMH) [E] <[hidden email]>
>>>>>>>
>>>>>>> On Sep 26, 2013, at 1:02 PM, Philippe GENDRE wrote:
>>>>>>>
>>>>>>>    Dear List,
>>>>>>>>
>>>>>>>>> I need to retrieve the red channel of an RGB image plus object as
>>>>>>>>> an
>>>>>>>>>
>>>>>>>>>  image
>>>>>>>>
>>>>>>>>  processor in a plugin.
>>>>>>>>>
>>>>>>>>> What is the best solution ?
>>>>>>>>>
>>>>>>>>>  Use the ImageProcessor.getChannel() method. Here is a JavaScript
>>>>>>>> example:
>>>>>>>>
>>>>>>>>      imp = IJ.openImage("http://imagej.****
>>>>>>>> nih.gov/ij/images/clown.jpg <http://nih.gov/ij/images/clown.jpg><ht
>>>>>>>> **tp://imagej.nih.gov/ij/images/**clown.jpg<http://imagej.nih.gov/ij/images/clown.jpg>
>>>>>>>> >
>>>>>>>>
>>>>>>>> ");
>>>>>>>>      ip = imp.getProcessor();
>>>>>>>>      red = ip.getChannel(1, null);
>>>>>>>>      new ImagePlus("Red Channel", red).show();
>>>>>>>>
>>>>>>>> In a plugin, it would look like this:
>>>>>>>>
>>>>>>>>      ImagePlus imp = IJ.openImage("
>>>>>>>> http://imagej.nih.gov/ij/****images/clown.jpg<http://imagej.nih.gov/ij/**images/clown.jpg>
>>>>>>>> <http://**imagej.nih.gov/ij/images/**clown.jpg<http://imagej.nih.gov/ij/images/clown.jpg>
>>>>>>>> >
>>>>>>>>
>>>>>>>> ");
>>>>>>>>      ImageProcessor ip = imp.getProcessor();
>>>>>>>>      ImageProcessor red = ((ColorProcessor)ip).****getChannel(1,
>>>>>>>> null);
>>>>>>>>
>>>>>>>>      new ImagePlus("Red Channel", red).show();
>>>>>>>>
>>>>>>>> -wayne
>>>>>>>>
>>>>>>>> --
>>>>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.****html<http://imagej.nih.gov/ij/list.**html>
>>>>>>>> <http://imagej.nih.gov/**ij/list.html<http://imagej.nih.gov/ij/list.html>
>>>>>>>> >
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>  --
>>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.****html<http://imagej.nih.gov/ij/list.**html>
>>>>>> <http://imagej.nih.gov/**ij/list.html<http://imagej.nih.gov/ij/list.html>
>>>>>> >
>>>>>>
>>>>>>
>>>>>>  --
>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.****html<http://imagej.nih.gov/ij/list.**html>
>>>>> <http://imagej.nih.gov/**ij/list.html<http://imagej.nih.gov/ij/list.html>
>>>>> >
>>>>>
>>>>>
>>>>>  --
>>> _____________________________
>>> Dr. Rob van 't Hof
>>> Reader
>>>
>>> Centre for Molecular Medicine
>>> MRC IGMM
>>> University of Edinburgh
>>> Western General Hospital
>>> Crewe Road, Edinburgh EH4 2XU
>>> United Kingdom
>>>
>>> Phone: (+44)-131-6511031
>>> email: [hidden email]
>>> _____________________________
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.****html<http://imagej.nih.gov/ij/list.**html>
>>> <http://imagej.nih.gov/**ij/list.html<http://imagej.nih.gov/ij/list.html>
>>> >
>>>
>>>  --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.**html<http://imagej.nih.gov/ij/list.html>
>>
>>
> --
> _____________________________
> Dr. Rob van 't Hof
> Reader
>
> Centre for Molecular Medicine
> MRC IGMM
> University of Edinburgh
> Western General Hospital
> Crewe Road, Edinburgh EH4 2XU
> United Kingdom
>
> Phone: (+44)-131-6511031
> email: [hidden email]
> _____________________________
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.**html<http://imagej.nih.gov/ij/list.html>
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html