我有一个二值图像(黑色和白色像素),我想将白色像素聚类成组(对象),这取决于彼此的距离,并检索每个聚类的质心。
(紫色框架)
我想检查一下聚类方法是否能提供我想要的结果,这意味着在知道值得之前,我试图避免自己实现一个算法。
OpenCV有一个方法来做我需要的事情吗?
我知道这是相当古老的,但也许这个答案可能会有帮助。
您可以使用partition,它将把一个元素集拆分为等效类。
您可以将等价类定义为给定欧几里得距离内的所有点。这可以是一个lambda函数(C++11)或一个函数(参见代码中的两个示例)。
您可以看到,在欧几里得距离内的所有白色像素都被分配到相同的集群(相同的颜色)。圆圈表示每个星团的中心。
代码:
#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>
using namespace std;
using namespace cv;
struct EuclideanDistanceFunctor
{
int _dist2;
EuclideanDistanceFunctor(int dist) : _dist2(dist*dist) {}
bool operator()(const Point& lhs, const Point& rhs) const
{
return ((lhs.x - rhs.x)*(lhs.x - rhs.x) + (lhs.y - rhs.y)*(lhs.y - rhs.y)) < _dist2;
}
};
int main()
{
// Load the image (grayscale)
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
// Get all non black points
vector<Point> pts;
findNonZero(img, pts);
// Define the distance between clusters
int euclidean_distance = 20;
// Apply partition
// All pixels within the the given distance will belong to the same cluster
vector<int> labels;
// With functor
//int n_labels = partition(pts, labels, EuclideanDistanceFunctor(euclidean_distance));
// With lambda function
int th2 = euclidean_distance * euclidean_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;
});
// Store all points in same cluster, and compute centroids
vector<vector<Point>> clusters(n_labels);
vector<Point> centroids(n_labels, Point(0,0));
for (int i = 0; i < pts.size(); ++i)
{
clusters[labels[i]].push_back(pts[i]);
centroids[labels[i]] += pts[i];
}
for (int i = 0; i < n_labels; ++i)
{
centroids[i].x /= clusters[i].size();
centroids[i].y /= clusters[i].size();
}
// Draw results
// Build a vector of random color, one for each class (label)
vector<Vec3b> colors;
for (int i = 0; i < n_labels; ++i)
{
colors.push_back(Vec3b(rand() & 255, rand() & 255, rand() & 255));
}
// Draw the points
Mat3b res(img.rows, img.cols, Vec3b(0, 0, 0));
for (int i = 0; i < pts.size(); ++i)
{
res(pts[i]) = colors[labels[i]];
}
// Draw centroids
for (int i = 0; i < n_labels; ++i)
{
circle(res, centroids[i], 3, Scalar(colors[i][0], colors[i][1], colors[i][2]), CV_FILLED);
circle(res, centroids[i], 6, Scalar(255 - colors[i][0], 255 - colors[i][1], 255 - colors[i][2]));
}
imshow("Clusters", res);
waitKey();
return 0;
}
我已经在网上搜索过了,我已经找到了一些方法来做我想做的事情,但是与我需要的相比,这些方法在效率上失败了。 我有一个kinect(使用Microsoft SDK),它当前正在获取一个删除背景的人,将结果保存在一个3通道的垫子中,并将该人从背景中删除。现在我需要裁剪图像以只适合那个人,忽略黑色区域。 这里是棘手的部分:我没有很多时间浪费在每个操作上(我还需要做其他几个操作,这应该是实时工作。我目前实现
在OpenCV python中,假设我们用cv2.imread读取一个图像,并得到一个BGR numpy数组。接下来我们使用cv2.inrange命令生成一个掩码。掩模具有相同的宽度/高度,并且每个掩模像素要么是黑色的,要么是白色的。 我必须先将掩码转换成BGR图像吗?如果是,怎么做? 编辑:我不想像在将蒙版应用到彩色图像中那样将整个蒙版应用到图像上。另一种表达我所想要的方式:将面具视为一个黑白图
本文向大家介绍C#图像颜色聚类高效方法实例,包括了C#图像颜色聚类高效方法实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#图像颜色聚类高效方法。分享给大家供大家参考。具体分析如下: 图像颜色聚类的方法有很多,但是对于视频监控而言,现有方法很难满足实时性的要求,这里介绍一种位屏蔽压缩的方法实现颜色聚类,可以满足实时性的要求。 位屏蔽法就是在3D的RGB真彩空间中近似均匀采样的颜色压缩
问题内容: 我在Python中具有以下测试代码以读取,设置阈值和显示图像: 我想计算带有特定标签(例如黑色)的图像内像素的数量。我怎样才能做到这一点 ?我看了OpenCV的教程,但没有找到任何帮助:-( 谢谢! 问题答案: 对于黑色图像,您将获得像素总数(行*列),然后从得出的结果中减去它。 对于其他值,您可以创建一个遮罩,该遮罩用于返回显示所需颜色/标签/值的所有位置的二进制遮罩,然后用于计算其
我有两种不同格式的图像。一个是BGR,一个是黑白(只有黑白,没有灰色的彩色像素)。它是相同的精确图像(相同的大小和像素)。我想在黑白图像中找到所有的白色像素,标记下来然后在BGR图像中找到完全相同的像素(显然它们在BGR图像中是着色的),并将它们着色为黑色。我试过了,但问题是黑白图像有1个通道,而BGR图像有3个通道,所以我失败了...我正在使用C++中的opencv。谢谢你的帮助!:)
使用k-means算法时需要指定分类的数量,这也是算法名称中“k”的由来。 k-means是Lloyd博士在1957年提出的,虽然这个算法已有50年的历史,但却是当前最流行的聚类算法! 下面让我们来了解一下k-means聚类过程: 我们想将图中的记录分成三个分类(即k=3),比如上文提到的犬种数据,坐标轴分别是身高和体重。 由于k=3,我们随机选取三个点来作为聚类的起始点(分类的中心点),并用红黄