将更接近的白色像素分组在一起,并在OpenCV中围绕它们绘制一个矩形 [英] Group closer white pixels together and draw a rectangle around them in OpenCV
本文介绍了将更接近的白色像素分组在一起,并在OpenCV中围绕它们绘制一个矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想对这些彼此靠近的白色像素进行分组,并使用C ++在OpenCV中围绕它们绘制一个矩形.
I want to group these white pixels that are closer to each other and draw a rectangle around them in OpenCV using C++.
原始图片:
预期结果:
我是OpenCV的新手.任何帮助将不胜感激.
I am new to OpenCV. Any help would be deeply appreciated.
推荐答案
You can group white pixels according to a given predicate using partition. In this case, your predicate could be: group all white pixels that are within a given euclidean distance.
然后您可以为每个组计算边界框,保留最大的框(在下面的红色),并最终将其放大(在下面的绿色):
You can then compute the bounding boxes for each group, keep the largest box (in RED below), and eventually enlarge it (in GREEN below):
代码:
#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>
using namespace std;
using namespace cv;
int main()
{
// Load the image
Mat3b img = imread("path_to_image", IMREAD_COLOR);
// Convert to grayscale
Mat1b gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
// Get binary mask (remove jpeg artifacts)
gray = gray > 200;
// Get all non black points
vector<Point> pts;
findNonZero(gray, pts);
// Define the radius tolerance
int th_distance = 50; // radius tolerance
// Apply partition
// All pixels within the radius tolerance distance will belong to the same class (same label)
vector<int> labels;
// With lambda function (require C++11)
int th2 = th_distance * th_distance;
int n_labels = partition(pts, labels, [th2](const Point& lhs, const Point& rhs) {
return ((lhs.x - rhs.x)*(lhs.x - rhs.x) + (lhs.y - rhs.y)*(lhs.y - rhs.y)) < th2;
});
// You can save all points in the same class in a vector (one for each class), just like findContours
vector<vector<Point>> contours(n_labels);
for (int i = 0; i < pts.size(); ++i)
{
contours[labels[i]].push_back(pts[i]);
}
// Get bounding boxes
vector<Rect> boxes;
for (int i = 0; i < contours.size(); ++i)
{
Rect box = boundingRect(contours[i]);
boxes.push_back(box);
}
// Get largest bounding box
Rect largest_box = *max_element(boxes.begin(), boxes.end(), [](const Rect& lhs, const Rect& rhs) {
return lhs.area() < rhs.area();
});
// Draw largest bounding box in RED
Mat3b res = img.clone();
rectangle(res, largest_box, Scalar(0, 0, 255));
// Draw enlarged BOX in GREEN
Rect enlarged_box = largest_box + Size(20,20);
enlarged_box -= Point(10,10);
rectangle(res, enlarged_box, Scalar(0, 255, 0));
imshow("Result", res);
waitKey();
return 0;
}
这篇关于将更接近的白色像素分组在一起,并在OpenCV中围绕它们绘制一个矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文