Hello. Please tell me if it is possible to somehow improve this code for finding the object mask? I need to find an object of an arbitrary shape on a white background, but it does it incorrectly. Any information would be helpful. Thanks!
struct comparator{
bool operator() (std::tuple<std::vector<cv::Point>, bool, double> t1,
std::tuple<std::vector<cv::Point>, bool, double> t2) {
return std::get<2>(t1) > std::get<2>(t2);
}
} comparator;
int main(int, char**)
{
// get image
cv::Mat image = cv::imread("C:\\Documents\\2.png");
cv::Mat grayImg;
// convert to greyscale
cv::cvtColor(image, grayImg, COLOR_BGRA2GRAY);
// cv::Mat canny;
// cv::Canny(grayImg,canny, 120, 255, 3);
// finding threshes
cv::Mat thresh;
cv::threshold(grayImg,thresh, 245, 255, THRESH_BINARY_INV);
// finding contours
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
findContours( thresh, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0) );
// finding max contour
std::vector<std::tuple<std::vector<cv::Point>, bool, double>> vec;
for(size_t i = 0; i < contours.size(); ++i){
vec.push_back(std::make_tuple(contours.at(i), cv::isContourConvex(contours.at(i)),cv::contourArea(contours.at(i))));
}
std::sort(vec.begin(), vec.end(), comparator);
std::tuple<std::vector<cv::Point>, bool, double> maxContour;
maxContour = vec.at(0);
// create mask
cv::Mat mask = Mat::zeros(thresh.size(), CV_8U);
cv::fillConvexPoly(mask, std::get<0>(maxContour), Scalar(255,0,0),8,0);
// bitwise
cv::Mat res;
cv::bitwise_and(image, image, res, mask);
// create transparent background
Mat dst;
Mat rgb[3];
split(image,rgb);
Mat rgba[4]={rgb[0],rgb[1],rgb[2], thresh};
merge(rgba,4,dst);
return 0;
}
Here is the output of the program. Unfortunately, I can only upload one image.