矩方法应用

  最近用到了矩方法对目标检测的结果进行后处理,包括求中心点,偏角和长短轴。基本步骤如下:
  • 第一步:将检测到物体的平行框位置作为ROI区域;
  • 第二步:对ROI区域进行预处理(灰度化、二值化);
  • 第三步:利用矩方法求出物体的矩(OPENCV::moments);
  • 第四步:利用矩分别计算中心点,偏角和长短轴。

理论部分可以参考这篇博客

一、求中心点

单通道图像的矩的面积为:
M00=ijV(i,j)
其中V(i,j)表示单通道图像在点(i,j)上的灰度值,一阶矩定义为:
M10=ijiV(i,j)
M01=ijjV(i,j)
通过一阶矩求出物体重心位置:
xc=M10M00
yc=M01M00

二、求偏角

物体的二阶矩定义为:

M20=iji2V(i,j)

M02=ijj2V(i,j)

M11=ijijV(i,j)

通过二阶矩计算偏转角度:

θ=12atan22bac

其中a=M20M00xc2,b=M11M00xcyc,c=M11M00yc2
求出的角度为x轴正方向与物体长轴所形成的角度,其范围为[90o,90o]x轴正向的逆时针方向为负,顺时针为正

三、求长短轴

长半轴r1和短半轴r2定义为:

r1=2(M20+M02+(M20M02)2+4M112)

r2=2(M20+M02(M20M02)2+4M112)

根据长短轴和中心点及偏角可以求出包含物体的斜框区域。

四、结果展示

红色点表示物体中心,黄色框是通过中心点、偏角和长短轴计算出四个顶点后画出来的。

五、代码

std::vector< std::vector< cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(cvImg, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
if (contours.size() > 0) {
	std::vector< cv::Point>cnt = contours[0];
	for (int i = 1; i < contours.size(); ++i) {
		if (contours[i].size() > cnt.size()) {
			cnt = contours[i];
		}
	}
        cv::Moments mu = cv::moments(cnt);
        cv::Point2f center = cv::Point2f(static_cast<float>(mu.m10 / mu.m00), static_cast<float>(mu.m01 / mu.m00));
}
posted @   半夜打老虎  阅读(1013)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示