说来难受,报名大疆夏令营要白色证件照,本想用画图工具直接喷漆一下解决的,谁知拍照时背景不均匀,用喷漆的结果是一点出现一个白点,渣渣不会用PS,只好opencv强上了
说来其实很简单,在hsv和gray分别割了一下,全部取与后,开运算消除一些噪点。本来还有后续操作:findContours(因为当时穿着和背景一样的蓝色,所以取轮廓时选择CV_RETR_EXTERNAL),drawContours,选择CV_FILLED,将人物全部涂成黑色,背景全为白色,然后分别于原图RGB三通道取加法,再合并起来得到最终结果。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("D:\\证件照\\1.jpg"), hsv, gray, bin, result;
namedWindow("test");
cvtColor(src, hsv, CV_BGR2HSV);
cvtColor(src, gray, CV_BGR2GRAY);
//imshow("test", src);
vector> contours;
vector hsv_channels, bgr_channels;
split(hsv, hsv_channels);
split(src, bgr_channels);
Mat hsv_hl, hsv_hh, hsv_s, hsv_v, color;
threshold(hsv_channels[0], hsv_hl, 100, 255, 0);
threshold(hsv_channels[0], hsv_hh, 119, 255, 1);
threshold(hsv_channels[1], hsv_s, 43, 255, 0);
threshold(hsv_channels[2], hsv_v, 80, 255, 0);
threshold(gray, bin, 100, 255, CV_THRESH_OTSU);
//imshow("bin", bin);
color = hsv_hl & hsv_hh & hsv_s & bin;
//imshow("hsv", color);
Mat close;
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
morphologyEx(color, close, CV_MOP_OPEN, kernel, Point(-1, -1), 2);
imshow("close", close);
add(bgr_channels[0], close, bgr_channels[0]);
add(bgr_channels[1], close, bgr_channels[1]);
add(bgr_channels[2], close, bgr_channels[2]);
merge(bgr_channels, result);
GaussianBlur(result, result, Size(7, 7), 1);
//resize(result, result, Size(295, 413));
imshow("result", result);
imwrite("D:\\证件照\\2.jpg", result);
waitKey(0);
return 0;
}
结果,有些地方棱角有点明显需要平滑一下,算了,反正到时候上传图片小很多又看不出来,就这样吧2333