Yesterday I was asked how to extract a contour from a given image in OpenCV. Here is an example. Imagine we got this tasty apple and we want to put it in another image (with a green background):
One solution is to first detect the edges of the apple with a Canny filter, then find the contours with OpenCV's findContours and create a mask with drawContours:
Finally copy the masked original image to the new image, which means only the areas of the contours will be copied… and you are done. You end up with a tasty apple on a green background:
In code this translates to (also on github):
#include "cv.h" #include "highgui.h" using namespace cv; using namespace std; int main() { // read in the apple (change path to the file) Mat img0 = imread("/home/philipp/images/apple.jpg", 1); Mat img1; cvtColor(img0, img1, CV_RGB2GRAY); // apply your filter Canny(img1, img1, 100, 200); // find the contours vector< vector<Point> > contours; findContours(img1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); // you could also reuse img1 here Mat mask = Mat::zeros(img1.rows, img1.cols, CV_8UC1); // CV_FILLED fills the connected components found drawContours(mask, contours, -1, Scalar(255), CV_FILLED); /* Before drawing all contours you could also decide to only draw the contour of the largest connected component found. Here's some commented out code how to do that: */ // vector<double> areas(contours.size()); // for(int i = 0; i < contours.size(); i++) // areas[i] = contourArea(Mat(contour[i])); // double max; // Point maxPosition; // minMaxLoc(Mat(areas),0,&max,0,&maxPosition); // drawContours(mask, contours, maxPosition.y, Scalar(1), CV_FILLED); // let's create a new image now Mat crop(img0.rows, img0.cols, CV_8UC3); // set background to green crop.setTo(Scalar(0,255,0)); // and copy the magic apple img0.copyTo(crop, mask); // show the images imshow("original", img0); imshow("canny", img1); imshow("cropped", crop); // imwrite("/home/philipp/apple_canny.jpg", img1); // imwrite("/home/philipp/apple_mask.jpg", mask); // imwrite("/home/philipp/apple_cropped.jpg", crop); waitKey(); return 0; }
Discussion