Reputation: 2990
I'm trying to read an image using OpenCV, get a part of it and show it in an NSImageView object. Here is how I'm doing.
cv::Mat im = cv::imread("/Users/maddev/Documents/R8.jpg");
cv::Mat reduced = im(cv::Rect(10, 10, 400, 400));
std::vector<unsigned char> data ;
unsigned char *ptr = reduced.data;
unsigned long size = reduced.total() * reduced.elemSize();
data.assign(ptr, ptr + size);
int cols = reduced.cols;
int rows = reduced.rows;
// to NSImage
unsigned char *pimage = &data[0];
NSBitmapImageRep *rep=[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:&pimage
pixelsWide:cols
pixelsHigh:rows
bitsPerSample:8
samplesPerPixel:3
hasAlpha:NO
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:cols*3
bitsPerPixel:24
];
NSImage *image = [[NSImage alloc] initWithCGImage:[rep CGImage] size:NSMakeSize(cols,rows)];
imageView.image = image;
which doesn't work, getting some garbage displayed.
But if I use same approach on im
object then everything works as expected.
Why reduced
cannot be displayed properly? Do I need to check anything else when creating NSBitmapImageRep
object?
Thx
P.S. Please ignore the vector stuff, this problem is part of a bigger solution and this is the only way I can bring the image bytes into main application from a cv:Mat picture.
Upvotes: 0
Views: 370
Reputation: 2990
I guess I'll answer to myself.
The solution was actually pretty easy, when a new cv::Mat
is created only the image header is copied, but it still point to the original image data, this leads to a wrong picture display.
All I had to is to use copyTo
method when creating the cropped version to actually copy needed data form big picture to the small one and then all worked as needed.
something like this
cv::Mat reduced;
orig(roi).copyTo(reduced);
Upvotes: 1