opencv像素值运算--判断角点(笔记)

c++ opencv像素值运算–辅助文档角点判断

现有一组vector< Point > 类型的corners 角点坐标(通过拟合文档边框,计算交点获得)
还有一Mat类型的二值化文档轮廓图(将文档图片经过Canny轮廓提取+findContours() 轮廓检测函数处理获得)
由于角点是以霍夫变换后的直线计算交点得来的,所以有些点并不在真正的文档角点上,需要判断哪些角点找对了位置,哪些没有。

为此暂时考虑尝试通过 获取文档轮廓图中 的角点附近 像素值的方法进行计算。

文档轮廓图(二值化)如下

在这里插入图片描述

首先参考Mat类型图像的像素点访问方法

代码如下:

写出获取角点附近8*8像素点的方式

//vector<Point> corners;//角点
//Mat Outlineimg;//二值图
Mat PointMat(Size(8, 8), Outlineimg.type());//8*8矩阵 用于存储角点附近图像

int BeginY = corners[num].y - 4, BeginX = corners[num].x - 4;//取点起始位
int EndY = corners[num].y + 4 , EndX = corners[num].x + 4;//取点终止位

for (int i =  BeginY ; i < EndY; i++)
{
	for (int j = BeginX; j < EndX; j++)
	{
		PointMat.at<uchar>(i - BeginY, j - BeginX) = Outlineimg.at<uchar>(i, j);
	}
}
imshow("show PointMat", PointMat);//打印角点附近图像

显示的角点附近图像如下:

在这里插入图片描述

存在问题:如果角点为与图像边界相邻的点时,那么在访问图像像素的时候,就可能发生访问越界的情况,而导致程序崩溃

解决方法:可以根据corners角点当前坐标与Mat图像尺寸来计算获取角点附近8*8像素图像所需的偏移量

代码如下

vector<Point> DocScan::CalPixValue(Mat& Outlineimg, vector<Point>& corners)//计算corners的像素值
{
	Mat PointMat(Size(8, 8), Outlineimg.type());
	vector<Point>  Markcorners;
	for (char num=0;num<corners.size();num++)
	{
		int dx, dy;//偏移量
        //---------------偏移量计算-------------
		if (corners[num].x - 0 < 4) {
			dx = 4 - corners[num].x;
		}else if (Outlineimg.cols - corners[num].x < 4) {
			dx = Outlineimg.cols - corners[num].x - 4;
		}else
			dx = 0;

		if (corners[num].y - 0 < 4) {
			dy = 4 - corners[num].y;
		}else if (Outlineimg.rows - corners[num].y < 4) {
			dy = Outlineimg.rows - corners[num].y - 4;
		}else
			dy = 0;

		int BeginY = corners[num].y - 4 + dy, BeginX = corners[num].x - 4 + dx;//取点起始位
		int EndY = corners[num].y + 4 + dy, EndX = corners[num].x + 4 + dx;//取点终止位
		//----------------访问角点附近的像素-----------------
		int whitenum = 0;
		for (int i = BeginY; i < EndY; i++)
		{
			for (int j = BeginX; j < EndX; j++)
			{
				PointMat.at<uchar>(i - BeginY, j - BeginX) = Outlineimg.at<uchar>(i, j);
				if (Outlineimg.at<uchar>(i, j) == 255)//找到白色像素
				{
					++whitenum;
				}
			}
		}
		if (whitenum >= 9)//如果白色像素数量>=9则可能为角点(不是太准确,具体参数根据个人需求修改)
		{
			cout << "got edge,whitenum= " << whitenum << endl;
			Markcorners.push_back(corners[num]);//符合条件的角点放入Markcorners中
		}
	}
	
	imshow("show PointMat", PointMat);//打印角点附近图像
	return Markcorners;//返回符合条件的角点
}

获取该函数返回的Markcorners,然后在在图上使用黄色圆圈来标出
如下图,黄色为可能的角点,红色为错误的角点(紫红色的点是霍夫变换拟合出来的线段端点,请忽略),可以看到一般情况下还是能分辨出正确的角点的。

在这里插入图片描述

但遇到这种情况的角点就检测不出来了(像素点数量=7)

在这里插入图片描述

那么单纯使用像素计算就没法满足需求了,可以考虑使用霍夫变换查找线条的方法计算两线夹角来判断其是否为角点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值