图像练习OpenCV(01)

提取出里面最大矩形的四个顶点坐标 

源图像

图像练习OpenCV(01)_第1张图片 

结果展示

图像练习OpenCV(01)_第2张图片

代码
void getLine(std::vector& data, int threshold)
{
	for (int x = 0; x < data.size(); x++)
	{
		if (0 == data[x])
		{
			continue;
		}

		int maxValue = 0, maxLoc = -1, i = -1;
		for (i = x; i < data.size(); ++i)
		{
			if (data[i] > maxValue)
			{
				maxValue = data[i];
				maxLoc = i;
			}
			if (data[i] == 0)
			{
				break;
			}
			data[i] = 0;
		}
		x = i;
		data[maxLoc] = 1;
	}
}

void rectangle_vertex_old()
{
	cv::Mat image = cv::imread("rectangle_vertex.jpg", cv::IMREAD_COLOR);

	cv::Mat gray;
	cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);

	cv::Mat binary = gray < 100;

	//计算x及y方向投影
	std::vector widthHist(binary.cols, -1);
	std::vector heightHist(binary.rows, -1);
	for (int y = 0; y < binary.rows; y++)
	{
		for (int x = 0; x < binary.cols; x++)
		{
			int value = (int)binary.at(y, x) / 255.0;
			heightHist[y] = heightHist[y] + value;
			widthHist[x] = widthHist[x] + value;
		}
	}

	int histThreshold = (int)(binary.rows * 0.7);
	//y方向的投影二值化
	for (int y = 0; y < binary.rows; y++)
	{
		if (heightHist[y] < histThreshold)
		{
			heightHist[y] = 0;
		}
	}

	//计算水平线的位置
	getLine(heightHist, histThreshold);

	histThreshold = (int)(binary.cols * 0.7);

	//x方向的投影二值化
	for (int y = 0; y < binary.cols; y++)
	{
		if (widthHist[y] < histThreshold)
		{
			widthHist[y] = 0;
		}
	}

	//计算垂直线的位置
	getLine(widthHist, histThreshold);

	//寻找左上点左下点
	cv::Point ptLeftTop(-1, -1), ptLeftDown(-1, -1);
	for (int x = 0; x < binary.cols; x++)
	{
		if (widthHist[x] == 1)
		{
			for (int y = 0; y < binary.rows; y++)
			{
				if (heightHist[y] == 1)
				{
					ptLeftTop.x = x;
					ptLeftTop.y = y;
				}
			}

			for (int y = binary.rows - 1; y > 0; y--)
			{
				if (heightHist[y] == 1)
				{
					ptLeftDown.x = x;
					ptLeftDown.y = y;
				}
			}
			break;
		}
	}

	//寻找右上点右下点
	cv::Point ptRightTop(-1, -1), ptRightDown(-1, -1);
	for (int x = binary.cols - 1; x > 0; x--)
	{
		if (widthHist[x] == 1)
		{
			for (int y = 0; y < binary.rows; y++)
			{
				if (heightHist[y] == 1)
				{
					ptRightTop.x = x;
					ptRightTop.y = y;
				}
			}

			for (int y = binary.rows - 1; y > 0; y--)
			{
				if (heightHist[y] == 1)
				{
					ptRightDown.x = x;
					ptRightDown.y = y;
				}
			}

			break;
		}
	}

	//画出4个点
	if (ptLeftTop != cv::Point(-1, -1))
	{
		cv::circle(image, ptLeftTop, 4, cv::Scalar(0, 0, 255, 0), 4);
	}
	if (ptLeftDown != cv::Point(-1, -1))
	{
		cv::circle(image, ptLeftDown, 4, cv::Scalar(0, 0, 255, 0), 4);
	}
	if (ptRightTop != cv::Point(-1, -1))
	{
		cv::circle(image, ptRightTop, 4, cv::Scalar(0, 0, 255, 0), 4);
	}
	if (ptRightDown != cv::Point(-1, -1))
	{
		cv::circle(image, ptRightDown, 4, cv::Scalar(0, 0, 255, 0), 4);
	}


	cv::namedWindow("src_old");
	cv::imshow("src_old", image);

	cv::waitKey();
}

你可能感兴趣的:(#,【OpenCV_练习】,opencv,计算机视觉,人工智能)