0

I ran into some trouble while extracting a matrix (cropping) using OpenCV. What's funny is if I don't execute the line to "crop" the image everything works fine. But if I do, I see horizontal multi-coloured lines in the place of the image.

This is to show that the cropping takes place correctly.

cv::imshow("before", newimg);

//the line that "crops" the image
newimg = newimg(cv::Rect(leftcol, toprow, rightcol - leftcol, bottomrow - toprow));

cv::imshow("after", newimg);

Before and after cropping

The code that follows is where I bind the image to a texture so that I can use it in OpenGL.

glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, newimg.cols, newimg.rows,
    0, GL_BGR, GL_UNSIGNED_BYTE, newimg.ptr());
glBindTexture(GL_TEXTURE_2D, 0);

And later to draw . . .

float h = size;
float w = size * aspectRatio; // of the image. aspectRatio = width / height
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + h, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + w, y + h, z);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + w, y, z);
glEnd();
glDisable(GL_TEXTURE_2D);

All of this works well and I see the proper image drawn in the OpenGL window when I comment out that line in which I had cropped the image. I have checked the image type before and after the cropping, but the only difference seems to be the reduced number of rows and columns in the final image.

Here is the image that gets drawn when cropping has been done.

Image produced when cropped

いちにち
  • 417
  • 6
  • 16
  • 1
    Is `newimg.ptr()` is returning a pointer that's compatible with the default value of `GL_UNPACK_ALIGNMENT`? – genpfault Feb 22 '16 at 01:21
  • I checked the type of image before and after cropping and both represented the same format `CV_8UC3`(16). I am sure that the conversion works since it displays the uncropped correctly in the OpenGL window when I comment out the cropping line. – いちにち Feb 22 '16 at 09:29

1 Answers1

0

After a bit of research I found out a way to solve the problem. The reason the image was looking distorted was because though the image had been cropped, newimg.step / newimg.elemSize() still showed the original size of the image. This meant that only the values of rows and columns had changed in the output image but pixels with no data in them which were no part of the image remained. That is possibly why the "after" image has a gray area on the right. I might be wrong about this theory since I don't have a deep understanding of the subject but it all started working properly once I inserted this line before calling glTexImage2D:

glPixelStorei(GL_UNPACK_ROW_LENGTH, newimg.step / newimg.elemSize());

Note: Since we are manipulating the pixel store of OpenGL, it's best to push the state before doing so:

glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);

And pop it out after you are done:

glPopClientAttrib();

This is to avoid the memory from getting corrupted. I thank genpfault for pointing me in the right direction.

See 8. Know your pixel store state for more details. https://www.opengl.org/archives/resources/features/KilgardTechniques/oglpitfall/

This post was also very useful.

Community
  • 1
  • 1
いちにち
  • 417
  • 6
  • 16