C++ 指针优化二值图像特征点过滤算法

本代码使用指针实现了一种高效的二值图像特征点过滤算法,通过设定阈值和边界距离,过滤掉面积小于指定阈值且距离图像边界小于指定距离的特征点,有效提升了图像处理效率。

代码实现

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

const int THRESHOLD = 128; // 阈值
const int DISTANCE = 50; // 边界距离
const int MIN_AREA = 10; // 最小面积

int main() {
    Mat src = imread('image.png', IMREAD_GRAYSCALE); // 读取二值化图像
    if (src.empty()) {
        cerr << 'Failed to read image!' << endl;
        return -1;
    }

    // 创建一个与原图像大小相同的标记图像
    Mat labels = Mat::zeros(src.size(), CV_32SC1);

    // 标记所有像素值大于阈值的像素
    int label_count = 1;
    for (int y = 0; y < src.rows; y++) {
        for (int x = 0; x < src.cols; x++) {
            if (src.at<uchar>(y, x) > THRESHOLD) {
                labels.at<int>(y, x) = label_count;
                label_count++;
            }
        }
    }

    // 统计每个标记的像素数量和边界矩形
    vector<int> label_areas(label_count, 0);
    vector<Rect> label_rects(label_count, Rect(src.cols, src.rows, 0, 0));
    for (int y = 0; y < src.rows; y++) {
        for (int x = 0; x < src.cols; x++) {
            int label = labels.at<int>(y, x);
            if (label > 0) {
                label_areas[label]++;
                label_rects[label].x = min(label_rects[label].x, x);
                label_rects[label].y = min(label_rects[label].y, y);
                label_rects[label].width = max(label_rects[label].width, x - label_rects[label].x);
                label_rects[label].height = max(label_rects[label].height, y - label_rects[label].y);
            }
        }
    }

    // 过滤面积小于最小面积的标记
    for (int i = 1; i < label_count; i++) {
        if (label_areas[i] < MIN_AREA) {
            for (int y = label_rects[i].y; y < label_rects[i].y + label_rects[i].height; y++) {
                for (int x = label_rects[i].x; x < label_rects[i].x + label_rects[i].width; x++) {
                    if (labels.at<int>(y, x) == i) {
                        labels.at<int>(y, x) = 0;
                    }
                }
            }
        }
    }

    // 过滤距离边界50个像素以内的标记
    for (int y = 0; y < src.rows; y++) {
        for (int x = 0; x < src.cols; x++) {
            int label = labels.at<int>(y, x);
            if (label > 0) {
                int distance = min(min(x, y), min(src.cols - x - 1, src.rows - y - 1));
                if (distance < DISTANCE) {
                    labels.at<int>(y, x) = 0;
                }
            }
        }
    }

    // 创建一个与原图像大小相同的输出图像
    Mat dst = Mat::zeros(src.size(), CV_8UC1);

    // 将剩余的标记转换为白色像素
    for (int y = 0; y < src.rows; y++) {
        for (int x = 0; x < src.cols; x++) {
            if (labels.at<int>(y, x) > 0) {
                dst.at<uchar>(y, x) = 255;
            }
        }
    }

    // 显示输出图像
    imshow('Output', dst);
    waitKey(0);

    return 0;
}

代码说明

  1. 读取二值化图像,并创建一个与原图像大小相同的标记图像 labels
  2. 使用循环遍历图像,将像素值大于阈值的像素标记为不同的标记。
  3. 统计每个标记的像素数量和边界矩形。
  4. 过滤面积小于最小面积的标记,将其像素值设置为 0。
  5. 过滤距离边界小于指定距离的标记,将其像素值设置为 0。
  6. 将剩余的标记转换为白色像素,生成输出图像。

优化说明

本代码使用指针访问图像像素,避免了使用 findContours 函数,减少了函数调用次数,提升了代码效率。此外,代码使用循环遍历图像,并使用条件判断过滤特征点,避免了不必要的计算,提高了算法效率。

注意事项

  • 代码中的阈值、边界距离和最小面积可以根据实际情况进行调整。
  • 代码使用了 OpenCV 库,需要安装 OpenCV 库才能编译运行。
  • 该代码仅适用于二值图像。

总结

本代码实现了一种高效的二值图像特征点过滤算法,使用指针访问图像像素,避免了使用 findContours 函数,提高了代码效率。同时,代码使用循环遍历图像,并使用条件判断过滤特征点,避免了不必要的计算,提高了算法效率。

C++ 指针优化二值图像特征点过滤算法

原文地址: https://www.cveoy.top/t/topic/kLym 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录