cv::intersectConvexConvex(polygon1Mat, polygon2Mat, intersectionMat); intersectionMat为空
时间: 2024-04-21 20:28:01 浏览: 16
`cv::intersectConvexConvex()` 函数用于计算两个凸多边形的交集,如果 `intersectionMat` 为空,则说明两个多边形没有交集。
可能的原因有:
1. 两个多边形之间没有交集。
2. 多边形的顶点或边界存在误差,导致无法正确计算交集。
3. 多边形的顶点或边界的数据结构不正确,导致无法正确计算交集。
可以检查一下多边形的数据是否正确,或者尝试使用其他方法来计算多边形的交集。
相关问题
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 for (const auto& vertex : polygon1) { double distance = cv::pointPolygonTest(polygon2, vertex, true); if (distance < 0) { // Vertex is outside polygon2 // Calculate area of polygon1 outside polygon2 cv::Mat polygon1Mat = cv::Mat(polygon1).reshape(1); cv::Mat polygon2Mat = cv::Mat(polygon2).reshape(1); cv::Mat intersectionMat; cv::intersectConvexConvex(polygon1Mat, polygon2Mat, intersectionMat); //if (cv::countNonZero(intersectionMat) == 0) std::vector<cv::Point2f> intersectionPolygon; intersectionMat.reshape(2).copyTo(intersectionPolygon); double intersectionArea = std::abs(cv::contourArea(intersectionPolygon)); double polygon1Area = std::abs(cv::contourArea(polygon1)); outsideArea = polygon1Area - intersectionArea; return false; } } // All vertices of polygon1 are inside polygon2 return true; } 上述代码正确吗
上述代码的逻辑存在问题。
首先,当 `distance < 0` 时,不能简单地认为顶点在多边形外部,而应该根据具体的情况来判断。如果顶点在多边形内部,`distance` 的值是正的,如果顶点在多边形边界上,`distance` 的值是 0,如果顶点在多边形外部,`distance` 的值是负的。
其次,在计算两个多边形的交集时,需要保证两个多边形都是凸多边形 。如果两个多边形中有一个不是凸多边形,则无法使用 `cv::intersectConvexConvex()` 函数计算交集。
最后,在计算多边形面积时,需要保证多边形的顶点按照顺序排列,否则计算结果可能不正确。
下面是一份修改后的代码,供参考:
```cpp
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
for (const auto& vertex : polygon1) {
double distance = cv::pointPolygonTest(polygon2, vertex, true);
if (distance < 0) {
// Vertex is outside polygon2
// Calculate area of polygon1 outside polygon2
cv::Mat polygon1Mat = cv::Mat(polygon1).reshape(1);
cv::Mat polygon2Mat = cv::Mat(polygon2).reshape(1);
std::vector<cv::Point2f> intersectionPolygon;
if (cv::isContourConvex(polygon1) && cv::isContourConvex(polygon2)) {
cv::Mat intersectionMat;
cv::intersectConvexConvex(polygon1Mat, polygon2Mat, intersectionMat);
if (cv::countNonZero(intersectionMat) > 0) {
intersectionMat.reshape(2).copyTo(intersectionPolygon);
}
} else {
cv::Rect rect1 = cv::boundingRect(polygon1Mat);
cv::Rect rect2 = cv::boundingRect(polygon2Mat);
cv::Rect intersectionRect = rect1 & rect2;
if (!intersectionRect.empty()) {
cv::Mat intersectionMat = cv::Mat::zeros(intersectionRect.size(), CV_8UC1);
cv::fillConvexPoly(intersectionMat, polygon1 - rect1.tl(), cv::Scalar(255));
cv::fillConvexPoly(intersectionMat, polygon2 - rect2.tl(), cv::Scalar(0), cv::LINE_AA);
std::vector<std::vector<cv::Point>> contours;
cv::findContours(intersectionMat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
if (!contours.empty()) {
intersectionPolygon = contours[0];
}
}
}
double intersectionArea = std::abs(cv::contourArea(intersectionPolygon));
double polygon1Area = std::abs(cv::contourArea(polygon1));
outsideArea = polygon1Area - intersectionArea;
return false;
}
}
// All vertices of polygon1 are inside polygon2
return true;
}
```
这份代码对于两个多边形进行了一些限制,只有当两个多边形都为凸多边形时,才会使用 `cv::intersectConvexConvex()` 函数计算交集。对于非凸多边形,使用包围盒和填充算法来计算交集。同时,对于计算多边形面积时,先将多边形按照顺序排列,再使用 `cv::contourArea()` 函数计算面积,以保证计算结果正确。
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 for (const auto& vertex : polygon1) { double distance = cv::pointPolygonTest(polygon2, vertex, true); if (distance < 0) { // Vertex is outside polygon2 // Calculate area of polygon1 outside polygon2 cv::Mat polygon1Mat = cv::Mat(polygon1).reshape(1); cv::Mat polygon2Mat = cv::Mat(polygon2).reshape(1); std::vector<cv::Point2f> intersectionPolygon; if (cv::isContourConvex(polygon1) && cv::isContourConvex(polygon2)) { cv::Mat intersectionMat; cv::intersectConvexConvex(polygon1Mat, polygon2Mat, intersectionMat); if (cv::countNonZero(intersectionMat) > 0) { intersectionMat.reshape(2).copyTo(intersectionPolygon); } } else { cv::Rect rect1 = cv::boundingRect(polygon1Mat); cv::Rect rect2 = cv::boundingRect(polygon2Mat); cv::Rect intersectionRect = rect1 & rect2; if (!intersectionRect.empty()) { cv::Mat intersectionMat = cv::Mat::zeros(intersectionRect.size(), CV_8UC1); cv::fillConvexPoly(intersectionMat, polygon1 - rect1.tl(), cv::Scalar(255)); cv::fillConvexPoly(intersectionMat, polygon2 - rect2.tl(), cv::Scalar(0), cv::LINE_AA); std::vector<std::vector<cv::Point>> contours; cv::findContours(intersectionMat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); if (!contours.empty()) { intersectionPolygon = contours[0]; } } } double intersectionArea = std::abs(cv::contourArea(intersectionPolygon)); double polygon1Area = std::abs(cv::contourArea(polygon1)); outsideArea = polygon1Area - intersectionArea; return false; } } // All vertices of polygon1 are inside polygon2 return true; }
这段代码是用于判断一个多边形是否被另一个多边形包含,并计算出多边形1与多边形2之间的“外部面积”。其中,函数的输入参数是两个多边形的顶点坐标向量,输出参数是外部面积。函数的实现过程是,对于多边形1的每个顶点,计算其到多边形2的距离。如果该距离小于0,则判定该顶点在多边形2外部,需要计算多边形1在多边形2外部的面积。计算面积的方法是,先判断两个多边形是否都是凸多边形,如果是则使用cv::intersectConvexConvex函数计算两个多边形的交集;如果不是,则使用cv::boundingRect函数计算两个多边形的外接矩形,并在该矩形内部构造一个新的二值图像,将多边形1和多边形2分别填充到该二值图像中,并使用cv::findContours函数找到交集多边形的轮廓。最后,使用cv::contourArea函数计算多边形1和交集多边形的面积,相减即为多边形1在多边形2外部的面积。如果多边形1的所有顶点都在多边形2内部,则返回true,否则返回false。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)