以下是使用C++和Opencv实现轮廓查找的底层代码,不调用findcontours函数:

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

using namespace cv;
using namespace std;

int main() {
    Mat img = imread("image.jpg");

    // Convert image to grayscale
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);

    // Apply thresholding
    Mat binary;
    threshold(gray, binary, 100, 255, THRESH_BINARY);

    // Find contours
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    for (int y = 0; y < binary.rows; y++) {
        for (int x = 0; x < binary.cols; x++) {
            if (binary.at<uchar>(y, x) == 255) {
                vector<Point> contour;
                contour.push_back(Point(x, y));
                int i = 0;
                while (i < contour.size()) {
                    Point p = contour[i];
                    if (binary.at<uchar>(p.y, p.x - 1) == 255) {
                        contour.push_back(Point(p.x - 1, p.y));
                        binary.at<uchar>(p.y, p.x - 1) = 0;
                    }
                    if (binary.at<uchar>(p.y, p.x + 1) == 255) {
                        contour.push_back(Point(p.x + 1, p.y));
                        binary.at<uchar>(p.y, p.x + 1) = 0;
                    }
                    if (binary.at<uchar>(p.y - 1, p.x) == 255) {
                        contour.push_back(Point(p.x, p.y - 1));
                        binary.at<uchar>(p.y - 1, p.x) = 0;
                    }
                    if (binary.at<uchar>(p.y + 1, p.x) == 255) {
                        contour.push_back(Point(p.x, p.y + 1));
                        binary.at<uchar>(p.y + 1, p.x) = 0;
                    }
                    i++;
                }
                contours.push_back(contour);
            }
        }
    }

    // Draw contours
    Mat drawing = Mat::zeros(binary.size(), CV_8UC3);
    for (int i = 0; i < contours.size(); i++) {
        drawContours(drawing, contours, i, Scalar(0, 0, 255), 2, LINE_8, hierarchy, 0);
    }

    // Display image
    imshow("Contours", drawing);
    waitKey(0);

    return 0;
}

该代码实现的是基于连通性的轮廓查找算法。该算法的原理是从二值化图像中找到所有连通区域,并将其转换为轮廓。具体步骤如下:

  1. 将彩色图像转换为灰度图像。
  2. 对灰度图像进行二值化处理,得到二值化图像。
  3. 从二值化图像中找到所有连通区域,对于每个连通区域,将其转换为轮廓。
  4. 绘制所有的轮廓。

该算法的公式如下:

  1. 将彩色图像转换为灰度图像:$gray = 0.299R + 0.587G + 0.114B$
  2. 对灰度图像进行二值化处理:$binary(x, y) = \begin{cases} 255 & \text{if } gray(x, y) > threshold \ 0 & \text{otherwise} \end{cases}$
  3. 查找所有连通区域:对于每个像素$(x, y)$,如果$binary(x, y) = 255$,则从该像素开始进行广度优先搜索,找到所有与该像素连通的像素,并将其标记为已访问。搜索过程中,将所有已访问的像素加入到当前连通区域的轮廓中。
  4. 绘制所有的轮廓:对于每个连通区域的轮廓,使用drawContours函数将其绘制到图像上
使用C++和Opencv实现轮廓查找底层代码不调用findcontours并且给出对应的算法原理和公式

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

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