简体   繁体   English

OpenCV 中的反向填充图像

[英]Inverse fill image in OpenCV

I'm new to OpenCv and have been using it for a small project.我是 OpenCv 的新手,并且一直在将它用于一个小项目。

I intend to fill a single channel image all over, except a rectangle region within the image.除了图像中的矩形区域外,我打算全部填充单个通道图像。

I have two problems.我有两个问题。

1) Filling a single channel image with black. 1)用黑色填充单通道图像。 (cvSet wont work on single channel) (cvSet 不能在单通道上工作)

2) Carrying out the fill all over the image except a rectangle region within the image. 2) 对整个图像进行填充,除了图像中的矩形区域。

Any solutions?有什么解决办法吗?

Here's a program that shows how to fill a single channel with black and also how to set the image to black with a mask.这是一个程序,展示了如何用黑色填充单个通道,以及如何使用蒙版将图像设置为黑色。

#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"

int main(int argc, const char * argv[]) {

    cv::Mat image;
    image = cv::imread("../../lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);

    if (!image.data) {
        std::cout << "Image file not found\n";
        return 1;
    }

    cv::namedWindow("original");
    cv::imshow("original", image);

    //Define the ROI rectangle
    cv::Rect ROIrect(100, 100, 200, 200);

    //Create a deep copy of the image
    cv::Mat fill(image.clone());
    //Specify the ROI
    cv::Mat fillROI = fill(ROIrect);
    //Fill the ROI with black
    fillROI = cv::Scalar(0);

    cv::namedWindow("fill");
    cv::imshow("fill", fill);
    cvMoveWindow("fill", 500, 40);

    //create a deep copy of the image
    cv::Mat inverseFill(image.clone());
    //create a single-channel mask the same size as the image filled with 1
    cv::Mat inverseMask(inverseFill.size(), CV_8UC1, cv::Scalar(1));
    //Specify the ROI in the mask
    cv::Mat inverseMaskROI = inverseMask(ROIrect);
    //Fill the mask's ROI with 0
    inverseMaskROI = cv::Scalar(0);
    //Set the image to 0 in places where the mask is 1
    inverseFill.setTo(cv::Scalar(0), inverseMask);

    cv::namedWindow("inverseFill");
    cv::imshow("inverseFill", inverseFill);
    cvMoveWindow("inverseFill", 1000, 40);
    // wait for key
    cv::waitKey(0);

    return 0;
}

Nested for loops would indeed be the quickest way.嵌套 for 循环确实是最快的方法。

Otherwise, consider making a buffer of identical size that's cleared using cvZero (all black).否则,请考虑创建一个大小相同的缓冲区,并使用 cvZero(全黑)清除。 Then, setROI to the region that you care about, and cvCopy into the temporary buffer.然后,将 ROI 设置为您关心的区域,并将 cvCopy 放入临时缓冲区。

A bit mask with cvAnd is also a nice and clean solution.带有 cvAnd 的位掩码也是一个不错且干净的解决方案。

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

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