[图像处理]边缘提取以及Harris角点检测

本文介绍了使用C++的CImg库进行图像处理,包括使用Sobel算子提取图像边缘,详细阐述了Harris角点检测的原理与实现过程,并通过调整模板尺寸和应用高斯滤波解决了检测问题。最终成功计算出A4纸的边缘直线方程及角点坐标。
摘要由CSDN通过智能技术生成

在本周的计算机视觉与模式识别作业中,给定输入图像是两张普通A4打印纸,上面可能有手写笔记或者打印内容但是拍照时角度不正。要求输出:
1. 图像的边缘;
2. 计算 A4纸边缘的各直线方程;
3. 提取A4纸的4个角点。
这里写图片描述
这里写图片描述


作业要求的是使用C++的CImg库,与OpenCV和MATLAB相比,CImg还是有点不太方便。

  • 图像边缘的提取
    这个任务比较简单,找一个像Prewitt算子、拉普拉斯算子或是其他算子,对输入图像进行卷积计算就可以了,原理是计算图像像素的变化,而变化剧烈的地方就是图像边缘出现的地方。
    这里我使用了Sobel算子来进行边缘提取并二值化。
    int sobelX[3][3] = { { -1,0,1 },{ -2,0,2 },{ -1,0,1 } };
    int sobelY[3][3] = { { 1,2,1 },{ 0,0,0 },{ -1,-2,-1 } };
    Sobel算子就是分别求图像X、Y方向的梯度,再求梯度平方和,小于某个阈值置为0,反之为255。
    最后结果如下:
    图1
    图2
  • Harris角点的检测
    主要时间都花费在这部分的实现上面了。这里推荐一篇文章,里面详解了Harris角点检测算法的原理、步骤,还给出了OpenCV实现的代码。
    http://www.cnblogs.com/ronny/p/4009425.html
    还有一些有帮助的文章:
    http://blog.csdn.net/l_inyi/article/details/8915116
    http://blog.csdn.net/berguiliu/article/details/24985825
    关键步骤如下:
    这里写图片描述
    而我自己则是在理解该文章所写算法的基础上,使用CImg库按步骤地搜索网上的资料,完成每一部分之后,检测出了角点。
    在实现过程中遇到的问题主要有:
    • 在求x、y方向梯度的时候,一开始使用的是一位的模板,导致检测到的角点过多,容易混淆。后来经过实验,改成了二维的3X3模板,效果较好;
    • 在第三步使用高斯加权的时候,我以为是对各梯度矩阵使用高斯分布的公式:这里写图片描述
      角点检测的结果:这里写图片描述
      明显不太对。
      后来查阅资料才认识到应该使用高斯低通滤波窗口对Ixx、Iyy、Ixy进行卷积。更正之后的结果:
      这里写图片描述这里写图片描述
  • 求边缘直线方程
    在Harris角点检测所得的图片当中,可以看到四个角的角点是独立出来的,能够比较容易地提取它们的坐标。因此可以利用Harris角点检测过程中计算的result数组来找到四个顶点的坐标,有了坐标之后四条直线的方程也就知道了。
    最后求得的方程:
    角点和方程

差点忘了贴代码:

// CV_HW2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include "CImg.h"
using namespace cimg_library;
using namespace std;

/*

CImg<> edgeDetect(CImg<> src) {
    int mask[3][3] = { {0,-1,0},{-1,4,-1},{0,-1,0} };
    int width = src.width();
    int height = src.height();
    CImg<double> newImg(width, height, 1, 3);
    newImg.fill(0);
    for (int i = 1; i < width - 1; i++) {
        for (int j = 1; j < height - 1; j++) {

            for (int k = 0; k < 3; k++) {
                double sum = 0.0;
                for (int row = 0; row < 3; row++) {
                    for (int col = 0; col < 3; col++) {
                        sum += mask[row][col] * src(i - 1 + row, j - 1 + col, k);
                    }
                }
                if (sum < 0)
                    sum = 0;
                else if (sum > 255)
                    sum = 255;
                newImg(i, j, k) = sum;
            }
        }
    }
    newImg.display();
    return newImg;
}
*/

CImg<> edgeDetect(CImg<> src) {
    int sobelX[3][3] = { { -1,0,1 },{ -2,0,2 },{ -1,0,1 } };
    int sobelY[3][3] = { { 1,2,1 },{ 0,0,0 },{ -1,-2,-1 } };
    int width = src.width();
    int height = src.height();
    CImg<double> G(width, height, 1, 3);
    CImg<double> newImg(width, height, 1, 3);
    newImg.fill(0);
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值