提取照片裏的PPT部分

這幾天上課老師說ppt不能拷。。。真是不爽,所以我寫了一個提取照片裏ppt部分的東西,其實原理很簡單,代碼貼出來大家就知道了,無非就是閾值化+輪廓提取+透視變換,效果還可以,不過我還是想再好一些,如果大家有什麼想法請告訴我。

#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	//讀取圖片並灰度化
	Mat src = imread("C:\\Users\\41608\\Pictures\\PPT\\微信圖片_20170524215655.jpg");
	imshow("src", src);
	Mat src_gray;
	cvtColor(src, src_gray, CV_RGB2GRAY);
	//閾值化
	Mat src_th;
	threshold(src_gray, src_th, 200, 255, THRESH_BINARY);
	imshow("src_th", src_th);

	//輪廓提取並剔除其他光亮區域
	Mat contour_image(src_th.size(), CV_8UC1, Scalar(0));
	vector<vector<Point>> contours;
	findContours(src_th, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	namedWindow("contour_image", CV_WINDOW_NORMAL);
	drawContours(contour_image, contours, 40, Scalar(255));
	imshow("contour_image", contour_image);

	cout << contourArea(contours[40]);

	int length = 0;

	//用方形包圍輪廓
	int j = 0;
	for (size_t i = 0; i < contours.size(); i++)
	{
		RotatedRect rct = minAreaRect(contours[i]);
		double x = rct.size.width;
		double y = rct.size.height;
		double sx = src.cols;
		double sy = src.rows;

		if ((x / y<1.5 || x / y>0.5) && (x*y>sx*sy / 8))
		{
			j = i;
		}
	}

	Mat result(src_th.size(), CV_8UC1, Scalar(0));
	drawContours(result, contours, j, Scalar(255));
	namedWindow("result", CV_WINDOW_NORMAL);
	imshow("result", result);

	//矩形擬合
	Mat rct_mat(src_th.size(), CV_8UC1, Scalar(0));
	RotatedRect rct = minAreaRect(contours[j]);
	double x = rct.size.width;
	double y = rct.size.height;
	length = (x + y) / 2;
	Point2f vertices[4];
	rct.points(vertices);

	for (size_t i = 0; i < 4; i++)
	{
		line(rct_mat, vertices[i], vertices[(i + 1) % 4], Scalar(255));
	}

	imshow("rct_mat", rct_mat);

	//透視變換
	Mat per_mat(Size(y, x), CV_8UC3, Scalar(0, 0, 0));
	Point2f src_point[4];
	Point2f dst_point[4];
	src_point[0] = vertices[0];
	src_point[1] = vertices[1];
	src_point[2] = vertices[2];
	src_point[3] = vertices[3];

	double sp_x = 0;
	double sp_y = 0;
	sp_x = rct.center.x;
	sp_y = rct.center.y;

	for (size_t i = 0; i < 4; i++)
	{
		if (src_point[i].x >sp_x&&src_point[i].y > sp_y)
		{
			dst_point[i] = Point2f(y, x);
		}
		else if (src_point[i].x > sp_x&&src_point[i].y < sp_y)
		{
			dst_point[i] = Point2f(y, 0);
		}
		else if (src_point[i].x < sp_x&&src_point[i].y > sp_y)
		{
			dst_point[i] = Point2f(0, x);
		}
		else if (src_point[i].x < sp_x&&src_point[i].y < sp_y)
		{
			dst_point[i] = Point2f(0, 0);
		}
	}

	/*dst_point[0]= Point2f(0,length);
	dst_point[1]= Point2f(0,0);
	dst_point[2]= Point2f(length,0);
	dst_point[3]= Point2f(length, length);*/

	Mat warp_mat(3, 3, CV_32FC1);
	warp_mat = getPerspectiveTransform(src_point, dst_point);
	warpPerspective(src, per_mat, warp_mat, per_mat.size());
	imshow("per_mat", per_mat);

	waitKey();

	return 0;
}

最後結果如下圖:

原圖我把有人的地方模糊了,畢竟不能讓人看出來。





希望大家多提意見

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章