opencv - 证件照改底色

       说来难受,报名大疆夏令营要白色证件照,本想用画图工具直接喷漆一下解决的,谁知拍照时背景不均匀,用喷漆的结果是一点出现一个白点,渣渣不会用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

你可能感兴趣的:(opencv)