理想情况下,边缘检测应该仅产生位于边缘上的像素的集合.实际上,由于噪声,不均匀照明引起的边缘间断,以及其他引入灰度值虚假的不连续的影响,这些像素并不能完全描述边缘特性. 因此,一般在边缘检测后面会紧跟连接算法,将边缘像素组合成有意义的边缘或区域边界.
局部处理是连接边缘点最简单的方法之一,是在每个点(x,y)处的一个小邻域内分析像素的特点,根据特定的准则,将所有的相似点连接起来,以形成根据特定准则满足相同特性像素的一条边缘
用于确定边缘像素相似性的两个主要的性质:
(1)梯度向量的强度 ![]()
(2)梯度向量的方向 ![]()
(x,y)表示一个像素点 (s,t)表示以(x,y)为中心的所有的邻域点
如果(s,t)既满足幅度准则又满足角度准则,那么我们将(s,t)连接到(x,y),在图像的每个像素点重复这一操作,当邻域的中心从一个点到另一个点时必须将已连接的点记录下来,简单的记录过程就是将每组被连接的像素分配不同的灰度值
根据以上原理得出步骤一:
1 计算图像x y方向的梯度 g_x,g_y
2 根据梯度矩阵计算幅度矩阵和角度矩阵 Mag angle
3 根据幅度准则和方向准则将图像赋予不同的灰度值
#include <iostream>
#include <opencv2/opencv.hpp>
#include<vector>
//
void CalMag(cv::Mat &src1,cv::Mat &src2,cv::Mat &dst1,cv::Mat &dst2){
for(int i=0;i<src1.rows;i++){
for(int j=0;j<src1.cols;j++){
float gx=src1.at<float>(i,j);
float gy=src2.at<float>(i,j);
dst1.at<float>(i,j)=std::sqrt(std::pow(gx,2)+std::pow(gy,2));
dst2.at<float>(i,j)=std::atan2(gy,gx);
}
}
}
void connect(cv::Mat &src1,cv::Mat &src2,cv::Mat &dst){
for(int i=1;i<src1.rows-1;i++){
for(int j=1;j<src1.cols-1;j++){
float magx=src1.at<float>(i,j);
float anglex=src2.at<float>(i,j);
for(int m=i-1;m<=i+1;m++){
for(int n=j-1;n<=j+1;n++){
float magy=src1.at<float>(m,n);
float angley=src2.at<float>(m,n);
if(m!=i&&n!=j) {
if (std::abs(magx - magy) <= 30 && std::abs(anglex - angley) <= 5) {
int dd = (int) (magx / (1.4));//原因是最大

这篇博客探讨了在边缘检测后如何使用局部处理来连接边缘像素,以形成连续的边缘或区域边界。介绍了两种主要的像素相似性性质:梯度向量强度和方向,并提供了简化步骤,包括计算梯度、幅度矩阵、角度矩阵以及像素连接。文章通过实例展示了处理前后的图像效果,特别指出仅考虑了水平和垂直边缘的情况,因为全角度旋转涉及到复杂性。
最低0.47元/天 解锁文章

5172

被折叠的 条评论
为什么被折叠?



