cv2.findcontours轮廓内外
时间: 2023-10-08 19:12:46 浏览: 118
cv2.findContours函数可以用来获取图像中的轮廓信息。这个函数的第一个返回值是轮廓的列表,第二个返回值是轮廓的层次结构。在这个函数中,通过调整第二个参数cv2.RETR_EXTERNAL和cv2.RETR_LIST可以选择获取轮廓的方式。当使用cv2.RETR_EXTERNAL参数时,函数只返回最外层的轮廓,而使用cv2.RETR_LIST参数时,函数返回所有的轮廓。因此,cv2.RETR_EXTERNAL返回的是轮廓的内部,cv2.RETR_LIST返回的是轮廓的内外都有。
相关问题
cv::findContours 查找 中心为空的圆圈的两个轮廓
中心为空的圆圈通常指的是环形,它有两个轮廓:内轮廓和外轮廓。如果您想查找中心为空的圆圈的两个轮廓,可以使用cv::findContours函数,并指定RETR_LIST模式。以下是一个示例代码:
```c++
cv::Mat img; // 二值化图像
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(img, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
// 遍历轮廓
for (int i = 0; i < contours.size(); i++) {
double area = cv::contourArea(contours[i]);
// 如果轮廓面积太小,则跳过
if (area < 100) continue;
// 判断轮廓是否为环形
std::vector<cv::Point> hull;
cv::convexHull(contours[i], hull);
double hull_area = cv::contourArea(hull);
if (std::abs(hull_area - area) > 1e-3) continue;
// 计算内外轮廓
std::vector<std::vector<cv::Point>> inner_contours, outer_contours;
cv::Mat mask = cv::Mat::zeros(img.size(), CV_8UC1);
cv::drawContours(mask, contours, i, cv::Scalar(255), cv::FILLED);
cv::findContours(mask, inner_contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
cv::drawContours(mask, inner_contours, -1, cv::Scalar(0), cv::FILLED);
cv::findContours(mask, outer_contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
// 绘制内外轮廓
cv::drawContours(img, inner_contours, -1, cv::Scalar(255), 2);
cv::drawContours(img, outer_contours, -1, cv::Scalar(255), 2);
}
```
上述代码首先遍历所有轮廓,计算其面积并判断是否太小。然后使用cv::convexHull函数计算轮廓的凸包,并计算凸包面积。如果轮廓面积与凸包面积差异较大,则认为它不是环形。然后使用cv::drawContours函数生成轮廓掩码,并使用cv::findContours函数查找内外轮廓。最后使用cv::drawContours函数绘制内外轮廓。
C++将内外轮廓合并为一个轮廓
要将内外轮廓合并为一个轮廓,可以使用C++中的轮廓逼近函数(cv::approxPolyDP)。首先,将内外轮廓合并为一个向量,然后使用轮廓逼近函数将其转换为多边形。
以下是一个简单的示例代码:
```
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// 读取图像并将其转换为灰度图像
Mat image = imread("contours.png");
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
// 将灰度图像二值化
Mat thresh;
threshold(gray, thresh, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 找到轮廓
vector<vector<Point>> contours;
findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 合并内外轮廓为一个向量
vector<Point> merged_contour;
for (size_t i = 0; i < contours.size(); i++) {
for (size_t j = 0; j < contours[i].size(); j++) {
merged_contour.push_back(contours[i][j]);
}
}
// 轮廓逼近
double epsilon = 5.0;
vector<Point> approx;
approxPolyDP(merged_contour, approx, epsilon, true);
// 绘制结果
Mat result(image.size(), CV_8UC3, Scalar(255, 255, 255));
drawContours(result, vector<vector<Point>>{approx}, 0, Scalar(0, 0, 255), 2);
// 显示结果
imshow("Result", result);
waitKey(0);
return 0;
}
```
在上述代码中,我们首先将图像转换为灰度图像,并将其二值化。接下来,我们找到轮廓并将内外轮廓合并为一个向量。然后,我们使用轮廓逼近函数将向量转换为多边形,并在最终结果中绘制多边形。
阅读全文