我使用OpenCV
开发了一个应用程序,它可以检测圆形形状并从二进制图像中获取质心。我现在想删除原始图像中未检测到的对象。所以我想知道是否有解决方案通过其质心从图像中提取对象。
这是我到目前为止所得到的:
for segmentation的结果:
// Read image
cv::Mat im = cv::imread( "11002847.bmp", cv::IMREAD_GRAYSCALE );
bitwise_not(im, im);
cv::Mat im2;
im.copyTo(im2);
//Detec the contour to get all the obeject centroid
std::vector<std::vector<cv::Point> > contours;
vector<cv::Vec4i> hierarchy;
findContours( im2, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
vector<cv::Moments> mu(contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
mu[i] = moments( contours[i], false );
}
ofstream file;
file.open("log.txt");
/// Get the mass centers:
vector<cv::Point2f> mc( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
file << mc[i].x << " "<< mc[i].y << endl;
}
file.close();
//Dtect the circular objects and get there centroid
// Setup SimpleBlobDetector parameters.
cv::SimpleBlobDetector::Params params;
// Change thresholds
//params.minThreshold = 10;
//params.maxThreshold = 200;
// Filter by Area.
params.filterByArea = true;
params.minArea = 1;
// Filter by Circularity
params.filterByCircularity = true;
params.minCircularity = 0.5;
// Filter by Convexity
params.filterByConvexity = true;
params.minConvexity = 0.1;
// Filter by Inertia
params.filterByInertia = true;
params.minInertiaRatio = 0.0;
// Storage for blobs
vector<cv::KeyPoint> keypoints;
// Set up detector with params
cv::SimpleBlobDetector detector(params);
// Detect blobs
detector.detect( im, keypoints);
ofstream file2;
file2.open("log2.txt");
for(vector<cv::KeyPoint>::iterator it = keypoints.begin(); it != keypoints.end(); ++it)
{
cv::KeyPoint k = *it;
file2 << k.pt.x << " "<< k.pt.y << endl;
}
file2.close();
// Draw detected blobs as red circles.
// DrawMatchesFlags::DRAW_RICH_KEYPOINTS flag ensures
// the size of the circle corresponds to the size of blob
cv::Mat im_with_keypoints;
drawKeypoints( im, keypoints, im_with_keypoints, cv::Scalar(0,0,255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
// Show blobs
cv::imwrite("keypoints.bmp", im_with_keypoints );
答案 0 :(得分:1)
我希望我理解你的问题,但为了以防万一,我会改写它。您想要删除顶部图像中的轮廓,这些轮廓在底部图像中未被检测为关键点(即在其中/周围没有红色圆圈)。
为了做到这一点,迭代所有contours
并使用pointPolygonTest检查每个轮廓是否存在KeyPoints
auto end = contours.end();
for (auto contour_itr = contours.begin(); contour_itr != end; ++contour_itr) {
auto keypoint_end = keypoints.end();
for (auto keypoint_itr = keypoints.begin(); keypoint_itr != keypoint_end; ++ keypoint_itr) {
auto contour = *contour_itr;
auto keypoint = *keypoint_itr;
if (cv::pointPolygonTest(contour, keypoint.pt, false) > 0) {
// do your thing here (e.g. store contour into an array or paint it into a new image
}
}
}
希望有所帮助