-
Simple Image Processing
Hello,
I am trying to do some very simple image processing, using OpenCV to access data from an image. What I want to do is check whether the "B" value of each RGB pixel is greater than 100 - and if so, set that "B" value to 255.
Here is my code:
Code:
IplImage* image = cvLoadImage("C:\\myPicture.bmp"); // Pointer to OpenCV IplImage structure
data = (char*)image -> imageData; // char buffer of image data
height = originalImage -> height; // height of image
width = originalImage -> width; // width of image
step = originalImage -> widthStep; // size in bytes of one line in image
for (int i = 0; i < height; i ++)
{
for (int j = 0; j < width; j ++)
{
if ((int)data[i * step + j * 3] > 100)
{
data[i * step + j * 3] = 255;
}
}
}
The problem is, the line which sets the "B" component to zero is never reached. In fact, using a breakpoint in debugging mode, I noticed that the value of data[i * step + j * 3] is always 0...
I have checked that the image is displaying correctly by displaying the image - so it is loading into the buffer ok.
I am able to do SOME image processing, such as inversion, where I simply say :
Code:
data[i * step + j * 3] = 255 - data[i * step + j * 3];
Also, if I assign a value to an element of the char array, that works too, such as making the entire image dark grey by saying :
Code:
data[i * step + j * 3] = 50;
BUT, when I actually try to compare the value in the char array to a number, such as in thresholding :
Code:
if (data[i * step + j * 3] > 100)
{
// do something
}
It doesn't work. I have tried checking the values of the array, for example :
Code:
int x = data[i * step + j * 3];
std :: cout << x;
...and it always tells me that the value of x is 0, no matter which element of the image buffer I am accessing.
It seems like it is something to do with converting between char and int...any ideas??
Thanks :)
-
So, what's the difference between image and originalImage?
I see nothing immediately wrong.
-
Ooops..."yeh originalImage" should just be "image". They are the same.
Can't work out why I can assign values to the data, but I cannot compare the values in an if statement.
If you say that it all looks fine, then I guess there is something going on at a deeper level I will have to look at...
-
Hmm. You may have a signedness issue.
Since the data pointer is char, any value greater than 127 will be treated as negative. When that casts to int, it's still negative, so your > 100 comparison will fail.
That still doesn't explain why everything in the array appears to be 0, but it's an issue. Try using an unsigned char * to point at the image data, instead of a char *.
Also, are you treating the pixel format correctly? Is this truly 24-bit RGB, or could there be a pad byte to make each pixel 32 bits wide?
-
Well, assuming that each rgb value is packed into 3 consecutive bytes, wouldn't your blue values be indexed by:
Code:
data[ i * step * 3 + j * 3 + 2 ]
Incidentally, you could make your life a lot easier if you just treated the buffer as an array of RGB's, instead of chars...
Code:
#pragma pack(push, 1)
struct rgb
{
unsigned char red, green, blue;
};
#pragma pack(pop)
IplImage* image = cvLoadImage("C:\\myPicture.bmp"); // Pointer to OpenCV IplImage structure
rgb* data = (rgb*)image -> imageData; // char buffer of image data
height = originalImage -> height; // height of image
width = originalImage -> width; // width of image
step = originalImage -> widthStep; // size in bytes of one line in image
for (int i = 0; i < height; i ++)
{
for (int j = 0; j < width; j ++)
{
if (data[i * step + j].blue > 100)
{
data[i * step + j].blue = 255;
}
}
}