使用了你给出的代码后报错:terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(4.5.0) /home/sniper/Downloads/opencv-4.5.0/modules/imgproc/src/contours.cpp:195: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'
时间: 2024-04-21 13:25:28 浏览: 164
这个错误的意思是你使用了不支持的图像格式或者图像格式组合。在使用 `cv.findContours()` 函数时,该函数只支持 CV_8UC1 格式的图像,而且只有在 mode 参数不等于 CV_RETR_FLOODFILL 时才支持 CV_32SC1 格式的图像。因此,你需要确保你的图像是符合要求的格式,并且 mode 参数设置正确。你可以尝试将图像转换为 CV_8UC1 格式,或者将 mode 参数设置为 CV_RETR_FLOODFILL。如果问题仍然存在,你可以提供更多的代码和上下文,以便我可以更好地帮助你解决问题。
相关问题
报错:terminate called after throwing an instance of 'std::length_error' what(): basic_string::_S_create 的原因
"terminate called after throwing an instance of 'std::length_error'" 这种错误通常发生在 C++ 中使用标准库中的 string 类型时,比如 `std::string`,当你试图创建一个新的 string 对象,并指定的长度超过了其内部缓冲区所能容纳的最大值时,就会抛出这个异常。
`what()` 函数返回的是异常信息,这里翻译成“基本字符串:_S_create”是在说遇到的问题与 string 类的一个构造函数 `_S_create` 相关,可能是尝试设置的字符串长度超过了初始化时预先分配的空间,这通常是由于动态内存溢出或者未正确计算所需内存大小导致的。
解决这类问题的关键是检查你的代码,确认是否在创建 string 时输入了合理的长度,或者确保有足够的空间来存储数据。如果需要动态增长,可以考虑使用 `reserve()` 函数预分配足够的内存。此外,记得处理并捕获 `std::length_error` 异常,避免程序突然终止。
但是运行后报错:terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(4.5.0) /home/sniper/Downloads/opencv-4.5.0/modules/imgproc/src/contours.cpp:1799: error: (-215:Assertion failed) (_contours.kind() == _InputArray::STD_VECTOR_VECTOR || _contours.kind() == _InputArray::STD_VECTOR_MAT || _contours.kind() == _InputArray::STD_VECTOR_UMAT) in function 'findContours'
这个错误通常是由于传递给 `findContours()` 函数的轮廓参数类型不正确导致的。
在你的代码中,`findContours()` 函数的第一个参数是一个 `cv::Mat` 类型的矩阵,而第二个参数 `intersectionPolygon` 是一个 `std::vector<cv::Point>` 类型的向量。这里的问题是,`findContours()` 函数期望的第二个参数是一个用于存储轮廓的输出向量,而你传递了一个点的向量。因此,你需要将 `intersectionPolygon` 声明为一个 `std::vector<std::vector<cv::Point>>` 类型的向量,以存储轮廓。
更改后的代码如下所示:
```
bool isPolygonInside(const std::vector<cv::Point>& polygon1, const std::vector<cv::Point>& polygon2, double& outsideArea) {
// Check if all vertices of polygon1 are inside polygon2
bool allInside = true;
for (const auto& vertex : polygon1) {
double distance = cv::pointPolygonTest(polygon2, vertex, true);
if (distance < 0) {
allInside = false;
break;
}
}
if (allInside) {
return true;
}
// Polygon1 is partially or completely outside polygon2
std::vector<std::vector<cv::Point>> intersectionPolygon; // 修改此处
if (cv::isContourConvex(polygon1) && cv::isContourConvex(polygon2)) {
cv::Mat intersectionMat;
cv::intersectConvexConvex(cv::Mat(polygon1), cv::Mat(polygon2), intersectionMat);
if (cv::countNonZero(intersectionMat) > 0) {
cv::findContours(intersectionMat, intersectionPolygon, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
}
} else {
std::vector<cv::Point> hull1, hull2;
cv::convexHull(polygon1, hull1);
cv::convexHull(polygon2, hull2);
std::vector<cv::Point> hullIntersection;
cv::convexHull(hull1, hullIntersection, false, false);
cv::fillConvexPoly(cv::Mat(hullIntersection), hull2, cv::Scalar(0), false);
cv::findContours(cv::Mat(hullIntersection), intersectionPolygon, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
}
if (intersectionPolygon.empty()) {
outsideArea = 0;
return false;
}
double intersectionArea = std::abs(cv::contourArea(intersectionPolygon[0])); // 修改此处
double polygon1Area = std::abs(cv::contourArea(polygon1));
outsideArea = polygon1Area - intersectionArea;
return true; // 修改此处
}
```
你需要将 `intersectionPolygon` 的类型从 `std::vector<cv::Point>` 改为 `std::vector<std::vector<cv::Point>>`,以及在计算交集面积时使用 `intersectionPolygon[0]` 来获取轮廓。
另外,最后一行需要返回 true,因为在计算出多边形1在多边形2外部的面积后,函数应该返回 true。
阅读全文