Recently, I encountered a problem when using the project: I read the image with opencv, And then I opened up a new space. below is the code
Byte * inputImage = NULL;
IplImage * image_get = NULL;
Image_get = cvLoadImage (imageName, 0 );
ImageWidth = image_get-> width;
ImageHeight = image_get-> height;
InputImage = new Byte (imageHeight * imageWidth );
InputImage = image_get-> imageData;
There is a problem at this time. I allocated an imageHeight * imageWidth space to inputimage. However, it is okay if the image I read is 800*600.
When it is 801*601, it is found that the processing result is not the same. Later, I found that the widthstep in image_get is 804, instead of 801.
The following is a reference by someone else: solve this problem.
IplImage Data Structure in OpenCV is prone to errors
If you have a little understanding of OpenCV, you know the IplImage used to store image data. Two of the attributes are worth your attention. If you are not careful about them, an error will occur (see the following example ):
The first is the width attribute, and the second is the widthStep attribute.
The former indicates the number of bytes per line of the image, and the latter indicates the number of bytes required to store a row of pixels.
In OpenCV, widthStep must be a multiple of 4 to achieve byte alignment, which is conducive to improving the computation speed.
If the width of the 8U single-channel image is 3, The widthStep is 4, and a byte is added. The line of this image requires four bytes, only the first three are used, and the last one is empty.
That is to say, the imageData size of an image with a width of 3 is 4*3 = 12 bytes.
It should be noted that the empty pixel is not invalid and can still be operated, which is the root cause of the error.
Example:
Error example: if there is a char * data Pointer pointing to the starting address of a 17*15 grayscale image (17 columns, 15 rows, we want to display the image data through the cvShowImage function. A more intuitive method is as follows:
... IplImage * image = cvCreateImage (cvSize (17, 15), 8, 1 );
Memcpy (image-> imageData, data, 17*15 );
CvNamedWindow ("window ");
CvShowImage ("window", image );
CvWaitKey ();
CvReleaseImage (& image );
CvDestroyWindow ("window ");......
You will find that the displayed image is grayed out in the lower left corner.
After reading this article, I hope you will not waste your time on this issue (shamed: I am depressed for a whole day ).
The reason is that, when cvCreateImage is used, OpenCV achieves byte alignment, so that each row of data actually has 16 bytes (one more). when memcpy is used, these extra bytes will give the corresponding data to "eat", because the data will not be displayed during cvShowImage. In this way, the second row will have one less byte, the third row contains two fewer bytes ,......, So the entire image is in the lower left corner!
After knowing this, you can change the memcpy statement as follows:
For (INT I = 0; I <15; I ++) {memcpy (image-> imagedata + image-> widthstep * I, Data + 17 * I, 17 );}
In this way, the program can run as we imagine.
Note: For 16-bit data, the data size of each row must be * 2, that is, "Data + 17 * I * 2, 17*2 ".
FR: http://blog.csdn.net/yihandk666/article/details/6960671