如何用C++结合OpenCV获取叶片等物体的面积?
基于OpenCV的叶片面积计算方案
你的思路方向是对的,接下来可以在现有代码基础上补充以下步骤,实现两片叶片的面积统计:
步骤1:提取边缘轮廓
Canny输出的是边缘线条,首先需要从边缘图中提取出叶片的轮廓,这是后续计算面积的基础:
// 定义轮廓和层级结构变量 std::vector<std::vector<cv::Point>> contours; std::vector<cv::Vec4i> hierarchy; // 提取外部轮廓(只保留最外层,忽略内部孔洞) cv::findContours(cimg, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
步骤2:计算并输出每个叶片的面积
利用OpenCV自带的contourArea函数可以直接计算轮廓包围的面积,同时可以过滤掉小噪声轮廓:
// 遍历所有轮廓,统计有效叶片的面积 for (size_t i = 0; i < contours.size(); i++) { double area = cv::contourArea(contours[i]); // 过滤面积过小的噪声轮廓,阈值可根据实际图像调整 if (area > 50) { std::cout << i+1 << "号叶片-" << static_cast<int>(area) << std::endl; } }
完整整合代码
把你的现有代码和补充部分整合起来,完整实现流程:
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { Mat img = imread("your_leaf_image.jpg"); // 替换为你的叶片图像路径 if (img.empty()) { cout << "无法读取图像" << endl; return -1; } imwrite("capture.png", img); imshow("capture", img); moveWindow("capture",10,10); Mat gimg, bimg, cimg; cvtColor(img, gimg, COLOR_BGR2GRAY); blur(gimg, bimg, Size(3, 3)); int lowthreshold = 50; // 可根据图像清晰度调整阈值 int highthreshold = 150; Canny(bimg, cimg, lowthreshold, highthreshold, 3); // 提取轮廓 vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(cimg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // 统计叶片面积 for (size_t i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]); if (area > 50) { cout << i+1 << "号叶片-" << static_cast<int>(area) << std::endl; } } waitKey(0); return 0; }
实用提示
- 如果Canny边缘提取效果不好,可尝试用阈值分割(
threshold或adaptiveThreshold)替代,背景单一的情况下阈值分割更稳定 - 调整Canny的高低阈值,确保叶片边缘完整闭合,避免轮廓断裂
- 若叶片内部有孔洞,可修改
findContours的检索模式为RETR_CCOMP,并计算包含孔洞的总面积
内容的提问来源于stack exchange,提问作者Official Wish
相关产品推荐
相关产品推荐

