我有一个包含图像像素坐标的Qvector。主要目标是将这些像素与彼此的距离进行分组,并从这些像素组中获取矩形。向量中的每个像素彼此不相近,这就是我想将它们分组的原因。
我正在使用openCv和Qt。我想避免使用OpenCV中的blobDetector这是非常慢的,如果可能的话,我自己做这个。
有人知道如何管理这个吗?
修改
让我们说白点是彼此接近的像素。主要目标是检测这些像素彼此接近并且能够获得这些像素的矩形。这可能吗?
EDIT2:
获取群集后,我尝试使用以下代码获取这些群集周围的边界矩形。我可能没有正确使用此功能。
cv::partition(cvCoordsTable, testVector, Dist(eqludianThreshold));
std::vector<cv::Rect> rectTable;
for(int in = 0; in < testVector.size(); in++)
{
rectTable.push_back(cv::boundingRect(cvCoordsTable.at(in)));
}
感谢您的帮助
答案 0 :(得分:3)
这首先是集群问题。由于您不知道群集(组)的数量,因此必须使用一些不需要群集数量作为输入的算法。你可以做简单的gains from it,它在C ++中有以下签名:
std::vector<cv::Point> pixelCoordinatesTable,
std::vector<int> labelsTable;
double threshold= 5;//Max eqludian distance between one cluster points
cv::partition(pixelCoordinatesTable, labelsTable, [&threshold](auto const& l, auto const& r){
return cv::norm(l - r))<threshold;
});
使用它的示例:
cv::boundingRect
另一个更成熟的选择是使用真正的聚类算法,如cv::partition。这是一种基于密度的聚类算法。你可以找到一个C ++ DBSCAN。
获得群集后(在任何方法中)只需在每个cluster
周围应用rectangle
即可获得所需的auto cluster_count = cv::partition(cvCoordsTable, testVector, Dist(eqludianThreshold)); // gettting the number of clusters
std::vector<cv::Rect> rectTable;
rectTable.reserve(cluster_count);//Optimiaztion
for(int in = 0; in < cluster_count; in++){
std::vector<cv::Point> temp;
temp.reserve(testVector.size());
for(size_t i=0;i<testVector.size();++i){
if(testVector[i]==in){
temp.emplace_back(rectTable[i]);
}
}
rectTable.emplace_back(cv::boundingRect(temp));
}
。
修改强>
解决矩形问题:
<md-input-container flex>
<label>Length</label>
<input type="number" ng-model="length" flex="80">
<span flex>seconds</span>
</md-input-container>
我确信有更好更快的方法,我只是在解释这个想法,你可以尽可能地优化它。
答案 1 :(得分:2)
struct Dist
{
double D;
Dist(double d) : D(d) {}
bool operator()(const Point &a, const Point &b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) < D;
}
};
vector<Point> centers; // e.g. from findContours -> boundingRect
vector<int> labels;
cv::partition(centers,labels,Dist(800));
cerr << Mat(labels).t() << endl;
[0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2, 2,2]