Omkar Khair
Omkar Khair

Reputation: 1384

Inverse fill image in OpenCV

I'm new to OpenCv and have been using it for a small project.

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. (cvSet wont work on single channel)

2) Carrying out the fill all over the image except a rectangle region within the image.

Any solutions?

Upvotes: 2

Views: 4596

Answers (2)

SSteve
SSteve

Reputation: 10738

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;
}

Upvotes: 3

peakxu
peakxu

Reputation: 6675

Nested for loops would indeed be the quickest way.

Otherwise, consider making a buffer of identical size that's cleared using cvZero (all black). Then, setROI to the region that you care about, and cvCopy into the temporary buffer.

A bit mask with cvAnd is also a nice and clean solution.

Upvotes: 0

Related Questions