Eugen
Eugen

Reputation: 2990

Convert OpenCV part of image to NSImage

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

Answers (1)

Eugen
Eugen

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

Related Questions