user1844505
user1844505

Reputation: 1307

open cv, rectangle region of interest referencing

I want to create a rectangle with particular coordinates width and height from an image.

And then splitting the channels and finally to thresholding the given channel in this area.

My problem is I want to reference to a area (rectangle) on the image.

this is my code: cv::Rect myROI(10, 20, 50, 50);
cv::Mat croppedImage = org_image(myROI);

after I operate on this croppedImage I want also, that the operation effects on the org_image.

I want to referece to the area and not copy the area (reference it).

How can I do that?


edit 1:

thank you for your answer first of all. I need a small solution additionally to my code above when I use
cv::threshold(croppedImage, croppedImage, thresh, 255, type);

the rectangular area is thresholded (but all channels), but not the particular channel I wanted, for example I want only the blue channel to be thresholded, I tried out everything, it doesnt work.

I tried out to split the rectangle, but it doesnt work.

By the way is the a solution to merge a splitted image too? This could help me If I could split by only referencing the croppedImage it would solve my problem I think.

So I only need to threshold one channel in a roi, please give me a complete solution. And I have to use splitting.

Thank you


Edit 2

So it don't work, see my code here... Operation on splitted channels doesnt have any effect to the cropped Image and respectively the original image too.

  Mat org_image = image.clone();
  cv::Rect myROI(0, 0, 5, 5);
  cv::Mat croppedImage = org_image(myROI);
  std::vector<cv::Mat> img_split(3);
  split(croppedImage, img_split);

  cv::threshold(img_split[1], img_split[1], thresh, 255, 0);

  for(int i=0; i < 3; i++)
  printf("img_split[%d].data[0] ==> adress: %p, ==> data: %d\n", i, &img_split[i].data[0], img_split[i].data[0]);
  printf("+++++++++++++++++\n");        
  for(int i=0; i < 3; i++)
  printf("     croppedImage[%d] ==> adress: %p, ==> data: %d\n", i, &croppedImage.data[i], croppedImage.data[i]);      
  printf("+++++++++++++++++\n");    
  for(int i=0; i < 3; i++)
  printf("org_image[%d] ==> adress: %p, data ->  %d\n", i, &org_image.data[i], org_image.data[i]);

The Output:

img_split[0].data[0] ==> adress: 0x846e8a0, ==> data: 212
img_split[1].data[0] ==> adress: 0x846e8d0, ==> data: 255
img_split[2].data[0] ==> adress: 0x846e910, ==> data: 220
+++++++++++++++++
     croppedImage[0] ==> adress: 0xb468d010, ==> data: 212
     croppedImage[1] ==> adress: 0xb468d011, ==> data: 220
     croppedImage[2] ==> adress: 0xb468d012, ==> data: 220
+++++++++++++++++
org_image[0] ==> adress: 0xb468d010, data ->  212
org_image[1] ==> adress: 0xb468d011, data ->  220
org_image[2] ==> adress: 0xb468d012, data ->  220

I dont have any more ideas.... :-(

Upvotes: 1

Views: 2394

Answers (1)

Alexander Gorban
Alexander Gorban

Reputation: 1238

Actually, after you operate on this croppedImage that operation will have effect on the org_image. You could use special constructor for this:

Mat::Mat(const Mat& m, const Rect& roi)

Here is example:

uchar vals[] = {1,1,1,1,
                1,1,1,1,
                1,1,1,1,
                1,1,1,1};
cv::Mat_<uchar> A(4,4,vals);
std::cout << "before:\n" << A << std::endl;

cv::Rect roi(1,1,2,2);
cv::Mat_<uchar> B( A, roi );
B.setTo(2);

std::cout << "after:\n" << A << std::endl;

output:

before:
 [1, 1, 1, 1;
  1, 1, 1, 1;
  1, 1, 1, 1;
  1, 1, 1, 1]
after:
 [1, 1, 1, 1;
  1, 2, 2, 1;
  1, 2, 2, 1;
  1, 1, 1, 1]

Upvotes: 1

Related Questions