You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++版OpenCV检测黑背景中的白方块并获取其中心与尺寸?

使用OpenCV C++检测黑背景中的白色方块并获取中心位置与尺寸

黑背景中的白色方块

需求描述

我希望检测黑背景中的每个白色方块,并获取每个方块的中心位置与尺寸。我正尝试使用C版OpenCV库实现该功能,运行环境为树莓派标准系统,已通过终端执行sudo apt-get install libopencv-dev命令安装最新版OpenCV库,但此前无OpenCV相关使用经验。我了解可以将图像以像素数据形式加载到cv::Mat类型变量中,也知道如何访问cv::Mat变量内的每个像素并获取其字节值。现在我需要找到能检测每个白方块、并返回其在图像中的中心位置与尺寸的函数,请问该需求是否可通过C版OpenCV实现?是否存在对应的函数?


解答

这个需求完全可以用OpenCV C++实现,不需要手动逐像素遍历(内置函数更高效),核心依赖轮廓检测相关的函数,具体实现步骤如下:

  1. 图像预处理

    • 若原图是彩色图,先用cv::cvtColor()转换为灰度图
    • 用cv::threshold()进行二值化处理,将白色方块与黑背景明确区分(白色区域设为255,黑色设为0)
  2. 轮廓提取

    • 使用cv::findContours()函数提取图像中的白色轮廓,推荐设置参数为RETR_EXTERNAL(只检测最外层轮廓)和CHAIN_APPROX_SIMPLE(压缩轮廓点,减少数据量)
  3. 计算方块的边界与中心

    • 对每个检测到的轮廓,调用cv::boundingRect()获取其外接矩形,返回的cv::Rect对象包含矩形左上角坐标(x,y)、宽度(width)和高度(height)
    • 中心位置可通过公式计算:中心x = rect.x + rect.width/2,中心y = rect.y + rect.height/2

示例代码

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

using namespace cv;
using namespace std;

int main() {
    // 加载图像
    Mat img = imread("your_image_path.png");
    if (img.empty()) {
        return -1;
    }

    // 转灰度图
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);

    // 二值化(阈值可根据实际图像调整)
    Mat binary;
    threshold(gray, binary, 127, 255, THRESH_BINARY);

    // 检测轮廓
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    // 遍历轮廓并计算参数
    for (size_t i = 0; i < contours.size(); i++) {
        Rect rect = boundingRect(contours[i]);
        Point center(rect.x + rect.width / 2, rect.y + rect.height / 2);
        
        // 输出结果
        printf("方块%d:中心坐标(%d,%d),尺寸:宽%d 高%d\n", 
               i+1, center.x, center.y, rect.width, rect.height);

        // 可选:在图像上绘制矩形和中心点
        rectangle(img, rect, Scalar(0,255,0), 2);
        circle(img, center, 3, Scalar(0,0,255), -1);
    }

    // 显示检测结果
    imshow("检测结果", img);
    waitKey(0);
    return 0;
}

注意事项

  • 若图像存在噪声,可先用cv::morphologyEx()做开运算去除小噪点
  • 二值化阈值需根据实际图像调整,也可使用cv::adaptiveThreshold()实现自适应阈值分割
  • 若需更精准的方块边界,可使用cv::minAreaRect()获取最小外接矩形,不过cv::boundingRect()已能满足基础需求

内容的提问来源于stack exchange,提问作者Runsva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:27:39