《数字图像处理》 第11章 表示和描述 学习笔记附部分例子代码(c++&opencv)

0. 前言

本章只学习了前三节……

VS安装Image watch插件请查看官网OpenCV: Image Watch: viewing in-memory images in the Visual Studio debugger

第三版教材中图片下载地址: book images downloads

vs2019配置opencv可以查看:VS2019 & Opencv4.5.4配置教程

前情回顾:
《数字图像处理》第三章 灰度变换和空间滤波 学习笔记附部分例子代码
《数字图像处理》第四章 频率域滤波 学习笔记附部分例子代码
数字图像处理第五章 图像复原和重建(内容较简单,就没有详细记录笔记)
《数字图像处理》第六章 彩色图像处理 学习笔记附部分例子代码
《数字图像处理》第七章 小波域多分辨率处理 学习笔记附部分例子代码
数字图像处理第八章 图像压缩 非重点
《数字图像处理》第九章 形态学图像处理 学习笔记附部分例子代码
《数字图像处理》第十章 图像分割 学习笔记附部分例子代码

1. 表示

1.1 边界追踪

处理的是二值图像,其目标和背景点分别标为1和0,Moore边界追踪算法的步骤如下:

  1. 找到图像左上角为1的点b0为边界起始点。b0左边的点为c0,从c0开始按顺时针方向考察b0的8邻域,找到的第一个值1的点为b1,令扫描到b1前的点为c1。

  2. 赋值b=b1,c=c1。

  3. 从c开始顺时针方向行进,找到第一个值1的点nk,其之前的点均为背景点。

  4. 赋值b=nk,c=nk-1。

  5. 重复step3和step4,直到b=b0且下一个边界点为b1。

1.2 链码

链码用于表示由顺次连接的具有指定长度和方向的直线段组成的边界

使用了opencv的findContours()drawContours(),具体形参的表示可以看补充

void ch11_test01(string path) {
   
   
    Mat image = imread(path, IMREAD_GRAYSCALE);
    if (image.empty()) {
   
   
        cout << "Unable to load the image\n";
        return;
    }
    // 创建一个纯黑画布
    Mat black(image.size(), CV_8U, Scalar(0));

    Mat filtered;
    blur(image, filtered, Size(9, 9));

    Mat result = Otsu(filtered);//该函数的实现请看第十章笔记的3.2节

    // 寻找轮廓
    vector<vector<Point>> contours;
    findContours(result, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    vector<Point> contour = contours[0];

    vector<int> freemaCode;
    Point currentPoint = contour[0];
    Point nextPoint;

    for (size_t i = 1; i < contour.size(); i++) {
   
   
        nextPoint = contour[i];

        // 计算方向
        int dx = nextPoint.x - currentPoint.x;
        int dy = nextPoint.y - currentPoint.y;
        // 转换为佛雷曼链码
        int code = -1;
        if (dx == 0 && dy == -1)      code = 0;
        else if (dx == 1 && dy == -1) code = 1;
        else if (dx == 1 && dy == 0)  code = 2;
        else if (dx == 1 && dy == 1)  code = 3;
        else if (dx == 0 && dy == 1)  code = 4;
        else if (dx == -1 && dy == 1) code = 5;
        else if (dx == -1 && dy == 0) code = 6;
        else if (dx == -1 && dy == -1)code = 7;
        // 添加到链码序列
        freemaCode.push_back(code);
        // 更新当前点
        currentPoint = nextPoint;
    }
    // 输出佛雷曼链码
    cout << "Freeman Chain Code: ";
    for (int code : freemaCode) {
   
   
        cout << code << " ";
    }
    cout << endl;

    // 在黑布上画出轮廓
    drawContours(black,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值