First time here? Check out the FAQ!

Ask Your Question
1

Create mask to select the black area

asked Oct 27 '15

alexandra gravatar image

updated Nov 2 '15

I have a black area around my image and i want to create a mask using OpenCv C++ that select just this black area so that i can paint it later. how Can i do that with out affect the image it self.

I try to converted to grayscale image and then using threshold to converted it to binary, but its affect my image since its contain black pixels.

image description

This is the code i used to find the biggest contoure

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp""
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( )
{
    Mat src;
    src = imread("pano1.jpg", CV_LOAD_IMAGE_COLOR);
    Mat gray;
    cvtColor(src, gray, CV_BGR2GRAY);
    threshold(gray, gray,30, 255,THRESH_BINARY_INV); //Threshold the gray
    imshow("gray",gray);
    int largest_area=0;
    int largest_contour_index=0;
    Rect bounding_rect;
    vector<vector<Point>> contours; // Vector for storing contour
    vector<Vec4i> hierarchy;
    findContours( gray, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
    // iterate through each contour.
    for( int i = 0; i< contours.size(); i++ )
    {

    //  Find the area of contour
    double a=contourArea( contours[i],false); 
    if(a>largest_area){
        largest_area=a;cout<<i<<" area  "<<a<<endl;
        // Store the index of largest contour
        largest_contour_index=i;               
        // Find the bounding rectangle for biggest contour
        bounding_rect=boundingRect(contours[i]);
    }
}

Scalar color(255,255,255);  // color of the contour in the
//Draw the contour and rectangle
drawContours( src, contours,largest_contour_index, color, CV_FILLED,8,hierarchy);
rectangle(src, bounding_rect,  Scalar(0,255,0),2, 8,0);

Mat inpainted;
inpaint(src, gray, inpainted, 3, INPAINT_NS);
imshow("inpainted image", inpainted);
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );
imshow( "Display window", src );    
waitKey(0);                                         
return 0;

}

This is the result of the code:

image description

Another question: if i want to crop the image instead of paint it, how can i do it??

Thanks in advance,

Preview: (hide)

Comments

how do you create the canvas image, because the black area around the stitched image is not exactly black.

theodore gravatar imagetheodore (Oct 27 '15)edit

The image is the result of stitching two image using opencv stitching module.

alexandra gravatar imagealexandra (Oct 27 '15)edit

but you do not initialize a canvas image where you are gonna put the stitching result beforehand?

theodore gravatar imagetheodore (Oct 27 '15)edit
  • You can do a findContour on the image, and the biggest one is the contour of your image, so just fill it and you have the mask (maybe you need to inverse the image, using absdiff)

  • You can do a waterShed starting form the 4 corners, so you can get that mask.

thdrksdfthmn gravatar imagethdrksdfthmn (Oct 27 '15)edit
1

@alexandra: can you provide a .png version of the image? The jpeg compression is causing some artifacts: as @theodore said, the black part is not truly black

LorenaGdL gravatar imageLorenaGdL (Oct 28 '15)edit

@theodore I try to use findContour but the biggest contour is not the contour of my image

alexandra gravatar imagealexandra (Oct 29 '15)edit

Can you post the result of the findContours?

thdrksdfthmn gravatar imagethdrksdfthmn (Oct 29 '15)edit

@alexandra as @LorenaGdL said can you post the image without the artifacts.

theodore gravatar imagetheodore (Nov 2 '15)edit

Have you tried it with the threshold set to 0 (you have put 30, so it is getting inside that tree)? You can do it 2 steps: split the image in 2 parts (top half and bottom half; or even 4 tl quarter, tr quarter...) and apply the algorithm. But the whatershed form each corner should be the best for resolving all the cases. ;)

thdrksdfthmn gravatar imagethdrksdfthmn (Nov 2 '15)edit

Thanks, but i think the best solution is to crop the image. do you know how to do it ??

alexandra gravatar imagealexandra (Nov 2 '15)edit

2 answers

Sort by » oldest newest most voted
5

answered Oct 27 '15

updated Oct 27 '15

OpenCV allows for easy indexation to create masks.

So imagine you want a cv::Mat with white pixels in the black zones of original image.

cv::Mat mask = cv::Mat::zeros(Original.size(), CV_8UC1);

mask.setTo(255, Original == 0);

Or

mask = (Original == 0);

This also works for > or < symbols, so, if you have

mask = (Original < 5);

Mask contains white pixels where Original has pixels lower than 5.

Preview: (hide)

Comments

t try to use this command but it not work right

alexandra gravatar imagealexandra (Oct 29 '15)edit
1

Share your code, otherwise I wont be able to help you

PedroBatista gravatar imagePedroBatista (Oct 29 '15)edit
0

answered Nov 3 '15

Since your image contains black pixels there is no simple and safe way to distinguish where are black pixels from background and where -- from you image. You'd better create rectangle mask for every source image and then transform every mask the same way you transform every source images for stitching. Then you will have a very precise and correct mask.

If you want just to crop it use Rect to create submatrix from matrix:

UMat crop = src(Rect(left, up, width, height));
Preview: (hide)

Comments

How can i determine the corners (left, up, width, height) ?? the image have some curves, so i need to select the right corners to crop the image and remove all black area.

alexandra gravatar imagealexandra (Nov 4 '15)edit

If you will create precise mask as described before you will be able to scan rows (and then columns) for mask background value presence. So the first mask top line without 'black' is your top crop rectangle side etc. Countnonzero will help you to find is it right slice or not.

drVit gravatar imagedrVit (Nov 4 '15)edit

Question Tools

1 follower

Stats

Asked: Oct 27 '15

Seen: 18,883 times

Last updated: Nov 02 '15