Входные данные: изображение лица
Проблема: пороговое изображение перед применением Canny для поиска контуров, но не возвращает маску
Желаемый вывод если вводится другое лицо, оно должно генерировать правильную маску (область лица белая и фон белый)
Пробовал с яблочной картиной .. отлично работает
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int main(){
Mat right=imread("front.jpg");
Mat img1;
cvtColor(right, img1, CV_RGB2GRAY);
threshold(img1,img1,160,255,cv::THRESH_BINARY);
Canny(img1, img1, 128, 350);
vector< vector<Point> > contours;
findContours(img1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
Mat mask = Mat::zeros(img1.rows, img1.cols, CV_8UC1);
drawContours(mask, contours, -1, Scalar(255), CV_FILLED);
normalize(mask.clone(), mask, 0.0, 255.0, CV_MINMAX, CV_8UC1);
imshow("original", right);
imshow("thresh",img1);
imshow("mask", mask);
waitKey(0);
return 0;
}
Вот изображение, которое я использовал
Пожалуйста, игнорируйте первые 3 комментария ниже
Используя этот код, создайте маску, отлично работающую с образцом, который вы указали в вышеприведенных комментариях.
Здесь предполагается, что ваш фон имеет любой цвет без других объектов.
Код ниже будет делать
Найти край
Укрепить край морфология операция.
Найдите самый большой контур по краю (всегда граница вашего переднего плана) и нарисуйте его, заполнив.
Иногда ваш контур не может быть закрыт снизу (без ребер снизу), поэтому контур заполнения не будет работать, поэтому для его закрытия сначала нужно найти ограничивающий прямоугольник для самого большого контура (передний план), а затем нарисовать нижнюю часть прямоугольника до края. изображение, а затем найти самый большой контур снова даст вам правильное изображение маски.
Rect R;
Mat findLargestContour(Mat thr){
vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
int largest_contour_index=0;
int largest_area=0;
Mat dst(thr.rows,thr.cols,CV_8UC1,Scalar::all(0)); //create destination image
findContours( thr, contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
{
double a=contourArea( contours[i],false); // Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i; //Store the index of largest contour
}
}
drawContours( dst,contours, largest_contour_index, Scalar(255,255,255),CV_FILLED, 8, hierarchy );
R= boundingRect( contours[largest_contour_index]);
return dst;
}
int main( )
{
Mat right=imread("1.jpg");
// blur(right,right,Size(3,3));
Mat gray;
cvtColor(right, gray, CV_RGB2GRAY);
int borderW=10;
//Mat ROI=gray(Rect(borderW,borderW,img1.cols-2*borderW,img1.rows-2*borderW));
Canny(gray, gray, 30, 255);
Size kernalSize (5,5);
Mat element = getStructuringElement (MORPH_RECT, kernalSize, Point(1,1) );
morphologyEx(gray, gray, MORPH_CLOSE, element );
imshow("canny", gray);
Mat largestCon=findLargestContour(gray.clone());
line(largestCon, Point(R.x,R.y+R.height), Point(R.x+R.width,R.y+R.height), Scalar(255),2,8,0);
Mat mask=findLargestContour(largestCon.clone());
Mat A;
right.copyTo(A,mask);
imshow("original", right);
imshow("dst", A);
imshow("mask", mask);
waitKey(0);return 0;
}
Посмотреть образец маски
Других решений пока нет …