繁体   English   中英

opencv如何以高性能方式可视化非矩形区域(roi)

[英]opencv how to visualize a non-rectangular region (roi) in a performant way

我有一个图像(cv :: Mat)和一个可被视为蒙版的ROI。 我想显示原始图像,并在上面混合了ROI。

我的蒙版比我的原始图像小:每个元素代表图像中的一块。 假设我的面具是这个(请注意我的面具不是矩形)

0  0  1
1  1  1
0  0  0

那么我想让(mask == 1)的部分保持不变,其余部分与颜色混合。 这是我的代码

cv::Mat blocks = image.clone;
uint npixcol = 32;
uint npixrow = 32;
for (uint ri = 0; ri < 480; ++ri)
    for (uint ci = 0; ci < 640; ++ci)
        {
        if (mask[ri * 640 + ci])
            cv::rectangle(blocks, cv::Rect(ci * npixcol, ri * npixrow, npixcol, npixrow), cv::Scalar(0, 0, 0), CV_FILLED, 8, 0);
        }
cv::addWeighted(image, 0.5, blocks, 0.5, 0, image, -1);

如果没有额外的“ clone”命令,我该怎么办呢?

使其更清楚; 这是我想要的示例(颜色并不重要)! 在此处输入图片说明

您的口罩颜色不变吗? 假设遮罩与图像的尺寸相同(您可以轻松缩放):

//Manually instead of addWeighted()
for (uint ri = 0; ri < 480; ++ri)
    for (uint ci = 0; ci < 640; ++ci)
        {
        if (mask[ri * 640 + ci])
        {
            image.at<uchar>(ri,ci) [0] = image.at<uchar>(ri,ci) [0] * weight_blue;
            image.at<uchar>(ri,ci) [1] = image.at<uchar>(ri,ci) [1] * weight_green;
            image.at<uchar>(ri,ci) [2] = image.at<uchar>(ri,ci) [2] * weight_red;
        }

        }    

根据您的评论,如果可以制作与原始图像尺寸相同的蒙版,则可以使用迭代器直接修改原始图像像素值。 这是一个独立的示例:

#include <cstdlib>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>


int
main(int argc, char *argv[])
{
  cv::Mat image = cv::imread(argv[1]);
  cv::Mat mask = cv::Mat::zeros(image.size(), CV_8U);
  // let's put some 1 in my test mask.
  cv::Mat roi = mask(cv::Rect(0,0,mask.cols/2, mask.rows/2));
  roi = 1;

  cv::Vec3b blue(255,0,0); // (B,G,R)
  float alpha = 0.5;
  // Let's have fun with iterators
  cv::MatConstIterator_<unsigned char> maskIter = mask.begin<unsigned char>();
  const cv::MatConstIterator_<unsigned char> maskIterEnd = mask.end<unsigned char>();
  cv::MatIterator_<cv::Vec3b> imageIter = image.begin<cv::Vec3b>();
  for (; maskIter != maskIterEnd; ++maskIter, ++imageIter) {
    if (*maskIter) {// mask == 1
      *imageIter = (1-alpha)*(*imageIter) + alpha*blue; // same as addWeighted 
    }
  }

  cv::namedWindow("image", 0);
  cv::imshow("image", image);
  cv::waitKey(0);
  return EXIT_SUCCESS;
}

基本上,您想检查一下自己是否在roi内。 然后,它应该返回一个指向原始图像的指针。 如果您不在室内,则希望具有某种颜色。

您可以使用自己的Mat包装器来做到这一点。

MyMat::at(int x, int y){
    if(inRoi(x,y)){
        return original.at(x,y);
    else
        return color(0,0,0);
}

我认为您不能将一个图像的subImage指向另一个图像。 (这意味着我认为您无法将蓝色图像中的像素重定向到原始图像上)

Mat blueImage;
Rect roi;
Mat roiInImage = blueImage(roi);
roiInImage.redirect = originalImage(roi); //don't think something like this is possible

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM