Ask Your Question
0

Thresholding in color image

asked 2015-03-12 00:36:16 -0600

jamesnzt gravatar image

I want to threshold an color image with particular range. If the input image pixel is with in that range it must be present in the output image. i.e. my range is : R: 122-200 ; G: 80-100 ; B:40-68

if a particular pixel of image I(x,y) is with in the range eg. I(100,130) { R:130; G:94; B: 53} then the values must be copied to output image O(x,y);

Inrange function gives binary image as output; i need RGB image as output.

i tried the following.

input image -> HSV;
HSV range selection;
HSV->RGB

input matrix: img;

output matrix : A

for (int i=0;i<img.rows;i++)
{
for(int j=0;j<img.cols;j++)
{
Vec3f intensity = img.at<Vec3b>(i,j);
float H=intensity.val[0];
float S=intensity.val[1];
float V=intensity.val[2];

if(  ((H>170 && H<=179) && (S>155 && S<255) && (V>150 && V<230))
{

       A.data[A.step[0]*i + A.step[1]* j + 0] = H;
           A.data[A.step[0]*i + A.step[1]* j + 1] =S;
           A.data[A.step[0]*i + A.step[1]* j + 2] = V; 
}
    }
}

the output is

image description

it works but slows down. is there any alternative?

edit retag flag offensive close merge delete

Comments

2

If you like pointer you can try too

for (int i=0;i<img.rows;i++)
    {
    float *hsv=img.ptr(i);
    unsigned char *dst=A.ptr(i);
    for(int j=0;j<img.cols;j++)
        {
        float H=*hsv++;
        float S=*hsv++;
        float V=*hsv++;

        if(  ((H>170 && H<=179) && (S>155 && S<255) && (V>150 && V<230))
               {
               *dst++ = H;
               *dst++ =S;
                *dst++ = V; 
               }
        }
    }
LBerger gravatar imageLBerger ( 2015-03-12 02:29:03 -0600 )edit

@berak I got this output from using inrange() . How can i get the output of image containing the rgb image from this? Inrange produces binary image as output

image description

jamesnzt gravatar imagejamesnzt ( 2015-03-12 03:01:09 -0600 )edit

@LBerger. Thanks for your code. but when i tried i got the following output.

image description

jamesnzt gravatar imagejamesnzt ( 2015-03-12 03:38:27 -0600 )edit
2

"How can i get the output of image containing the rgb image from this?" - use it as a mask with binary_and() or similar.

berak gravatar imageberak ( 2015-03-12 03:50:38 -0600 )edit

I have read your code too fast : your data image was not CV_32F but was byte

for (int i=0;i<img.rows;i++)
    {
    unsigned char  *hsv=img.ptr(i);
    unsigned char *dst=A.ptr(i);
    for(int j=0;j<img.cols;j++)
        {
        float H=*hsv++;
        float S=*hsv++;
        float V=*hsv++;

        if(  ((H>170 && H<=179) && (S>155 && S<255) && (V>150 && V<230))
               {
               *dst++ = H;
               *dst++ =S;
                *dst++ = V; 
               }
        }
    }

this code suppose that your data are CV_8UC3 for img and A

LBerger gravatar imageLBerger ( 2015-03-12 05:08:40 -0600 )edit
1

@LBerger, you only increase your pointer if it found a value inside the range ? that's why it's only drawing all red pixels on the left side, but not black ones. you will need something like:

    if ( (H>170 && H<=179) && (S>155 && S<255) && (V>150 && V<230) ) {
        *dst++ = H;
        *dst++ = S;
        *dst++ = V; 
    } else {
         dst++;
         dst++;
         dst++;
  }
berak gravatar imageberak ( 2015-03-12 05:16:15 -0600 )edit

@berak is correct. if the value of pixel is with in the range assign that value. else increment the pointer to skip that pixel.

jamesnzt gravatar imagejamesnzt ( 2015-03-12 05:38:22 -0600 )edit

@berak You're right. That's what happen to me when I don't test my code! thanks

LBerger gravatar imageLBerger ( 2015-03-12 07:50:40 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2015-03-12 05:28:34 -0600

jamesnzt gravatar image

updated 2015-03-12 05:44:00 -0600

I got it working

cvtColor(src,img,CV_BGR2HSV);  //convering src(RGB) to img(HSV)

inRange(img,Scalar(170,155,150),Scalar(180,255,230),h1);  //creating mask using inRange.

src.copyTo(out,h1);   // copying src(RGB) image to out with mask;

This works for me Thanks @berak and

cvtColor(src,img,CV_BGR2HSV);

Mat A(src.size(),src.type(),Scalar::all(0));
for (int i=0;i<img.rows;i++)
    {
    unsigned char  *hsv=img.ptr(i);
    unsigned char *dst=A.ptr(i);
    for(int j=0;j<img.cols;j++)
        {
        unsigned char H=*hsv++;
        unsigned char S=*hsv++;
        unsigned char V=*hsv++;


 if ( (H>170 && H<=179) && (S>155 && S<255) && (V>150 && V<230) ) {
        *dst++ = H;
        *dst++ = S;
        *dst++ = V; 
    } else {
         dst++;
         dst++;
         dst++;
  }
    }
}

cvtColor(A,out,CV_HSV2BGR);

this also works thanks @LBerger

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-03-12 00:36:16 -0600

Seen: 1,070 times

Last updated: Mar 12 '15