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

需求描述
我希望检测黑背景中的每个白色方块,并获取每个方块的中心位置与尺寸。我正尝试使用C版OpenCV库实现该功能,运行环境为树莓派标准系统,已通过终端执行sudo apt-get install libopencv-dev命令安装最新版OpenCV库,但此前无OpenCV相关使用经验。我了解可以将图像以像素数据形式加载到cv::Mat类型变量中,也知道如何访问cv::Mat变量内的每个像素并获取其字节值。现在我需要找到能检测每个白方块、并返回其在图像中的中心位置与尺寸的函数,请问该需求是否可通过C版OpenCV实现?是否存在对应的函数?
解答
这个需求完全可以用OpenCV C++实现,不需要手动逐像素遍历(内置函数更高效),核心依赖轮廓检测相关的函数,具体实现步骤如下:
图像预处理
- 若原图是彩色图,先用
cv::cvtColor()转换为灰度图 - 用
cv::threshold()进行二值化处理,将白色方块与黑背景明确区分(白色区域设为255,黑色设为0)
- 若原图是彩色图,先用
轮廓提取
- 使用
cv::findContours()函数提取图像中的白色轮廓,推荐设置参数为RETR_EXTERNAL(只检测最外层轮廓)和CHAIN_APPROX_SIMPLE(压缩轮廓点,减少数据量)
- 使用
计算方块的边界与中心
- 对每个检测到的轮廓,调用
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
相关产品推荐
相关产品推荐

