计算机视觉class4

要点

1.图像膨胀/腐蚀
2.直线检测(hough变换)
数学形态学的简单应用

解释

1.图像膨胀/腐蚀
腐蚀与膨胀,概念自行参考

2.直线检测(hough变换)
来一段套路熟悉下这是个什么鬼?
Hough变换是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为Hough变换的结果。简单而言就是运用两个坐标之前的变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转换为统计峰值的问题。
tip:在使用Hough变换之前,首先要对图像进行边缘检测,Hough变换的直线输入只能是边缘二值图像。

3.形态学的简单应用
利用各个不同的结构体进行膨胀和腐蚀以达到一个角点检测的目的。
(千言万语不如代码能说明问题)

程序

1.膨胀/腐蚀

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;

int main()
{
    Mat srcImage = imread("F:\\c_code\\week6_3\\week6_3\\1.png",0);
    imshow("src", srcImage);
    Size s1(5, 5);
    Mat element = getStructuringElement(MORPH_RECT, s1);
    std::cout << s1 << std::endl;
    Mat out;
    Mat dilateOut;
    dilate(srcImage, dilateOut, element);
    erode(srcImage, out, element);
    imshow("erode", out);
    imshow("dilate", dilateOut);
    Mat afterErodeSub = srcImage - out;
    Mat afterDilateSub = dilateOut - srcImage;
    imshow("subDilate", afterDilateSub);
    imshow("subErode", afterErodeSub);
    waitKey(0);
    return 0;
}

这里写图片描述这里写图片描述这里写图片描述
仅放三张图示意一下,还有做出的差值图像显示边缘,5*5的结构体。这些结果请自行查看。

Hough变换

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv)
{
    Mat srcImage = imread("F:\\c_code\\week7_2\\week7_2\\5.png");    
    Mat midImage, dstImage;  


    Canny(srcImage, midImage, 50, 200, 3);  
    cvtColor(midImage, dstImage, CV_GRAY2BGR); 


    vector<Vec4i> lines;  
    HoughLinesP(midImage, lines, 1, CV_PI / 180, 180, 50, 10);


    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i l = lines[i];
        line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 2, CV_AA);
    }


    imshow("srcImage", srcImage);


    imshow("cannyImage", midImage);


    imshow("result", dstImage);

    waitKey(0);

    return 0;
}




这里写图片描述这里写图片描述这里写图片描述
这个阈值调起来比较麻烦一点。。。

3.简单应用

#include <iostream>      
#include <opencv2/core/core.hpp>      
#include <opencv2/highgui/highgui.hpp>   
#include <opencv/cv.h>  

using namespace std;
using namespace cv;

class MorphoFeatures{

private:
    //用于生成二值图像的阈值  
    int ithreshold;
    //角点检测中用到的结构元素  
    Mat cross;
    Mat diamond;
    Mat square;
    Mat x;
    void applyThreshold(Mat &result);
public:
    MorphoFeatures() :ithreshold(50), cross(5, 5, CV_8U, Scalar(0)), diamond(5, 5, CV_8U, Scalar(1)), square(5, 5, CV_8U, Scalar(1)), x(5, 5, CV_8U, Scalar(0)){

        //创建十字形元素  
        for (int i = 0; i < 5; i++)
        {
            cross.at<uchar>(2, i) = 1;
            cross.at<uchar>(i, 2) = 1;
        }

        //创建菱形元素  
        diamond.at<uchar>(0, 0) = 0;
        diamond.at<uchar>(0, 1) = 0;
        diamond.at<uchar>(1, 0) = 0;
        diamond.at<uchar>(4, 4) = 0;
        diamond.at<uchar>(3, 4) = 0;
        diamond.at<uchar>(4, 3) = 0;
        diamond.at<uchar>(4, 0) = 0;
        diamond.at<uchar>(4, 1) = 0;
        diamond.at<uchar>(3, 0) = 0;
        diamond.at<uchar>(0, 4) = 0;
        diamond.at<uchar>(0, 3) = 0;
        diamond.at<uchar>(1, 4) = 0;

        //创建x形元素  
        for (int i = 0; i < 5; i++)
        {
            x.at<uchar>(i, i) = 1;
            x.at<uchar>(4 - i, i) = 1;
        }

    }

    Mat getEdges(const Mat &image);
    void setThreshold(float t);
    Mat getCorners(const Mat&image);
    void drawOnImage(const Mat &binary, Mat &image);
};

//获取二值的边缘图像  
void MorphoFeatures::applyThreshold(Mat &result){

    //使用阈值化  
    if (ithreshold > 0)
    {
        threshold(result, result, ithreshold, 255, THRESH_BINARY);
    }
}

//morphologyEx + 合适的滤波器实现直线的检测  
Mat MorphoFeatures::getEdges(const Mat &image){

    //得到梯度图  
    Mat result;
    morphologyEx(image, result, MORPH_GRADIENT, Mat());
    //阈值化以得到二值图像  
    applyThreshold(result);
    return result;
}

//设置直方图的阈值[0,1]  
void MorphoFeatures::setThreshold(float t){

    ithreshold = t;
}

//连接使用这些结构以得到最终的角点映射图  
Mat MorphoFeatures::getCorners(const Mat&image){

    Mat result;
    //十字形膨胀  
    dilate(image, result, cross);
    //菱形腐蚀  
    erode(result, result, diamond);
    Mat result2;
    //X形膨胀  
    dilate(image, result2, x);
    //方形腐蚀  
    erode(result2, result2, square);
    //通过对两张图像做差值得到角点图像  
    absdiff(result2, result, result);
    //阈值化以得到二值图像  
    applyThreshold(result);

    return result;
}

//在二值图像中的每个检测点上绘制一个圆  更好的可视化结果  
void MorphoFeatures::drawOnImage(const Mat &binary, Mat &image){

    Mat_<uchar>::const_iterator it = binary.begin<uchar>();
    Mat_<uchar>::const_iterator itend = binary.end<uchar>();

    //遍历每个像素  
    for (int i = 0; it != itend; ++it, ++i)
    {
        if (*it)
            circle(image, Point(i%image.step, i / image.step), 5, Scalar(255, 0, 0));
    }
}

int main(){

    Mat image = cvLoadImage("F:\\c_code\\week7_3_new\\week7_3_new\\1.png");
    Mat grayImage;
    cvtColor(image, grayImage, CV_BGR2GRAY);

    //显示原图  
    namedWindow("Image");
    imshow("Image", grayImage);

    MorphoFeatures morpho;
    //得到角点  
    Mat corners;
    corners = morpho.getCorners(grayImage);
    //在图像中显示角点  
    morpho.drawOnImage(corners, grayImage);

    namedWindow("Corners on Image");
    imshow("Corners on Image", grayImage);

    waitKey(0);
    return 0;
}

这里写图片描述这里写图片描述

草草结束。。。。(好不容易考完了泛函,接下来该认真做事了)
放一张美照结束
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值