您可以使用出色的ImageMagick,它已安装在大多数Linux发行版中,并且可用于OS X,其他良好的操作系统和Windows。它包括
“ Connected Components”
我正在尝试寻找起点,但是我似乎找不到正确的答案。我非常感谢您的指导。我也不知道适当的术语,因此不知道标题。
基本上,我希望能够提取像素的斑点,然后找到中心点。
我知道这是两个单独的问题,但是我认为如果有人可以做到,那么他们可以做到第一个。我正在使用MATLAB,但想编写自己的代码,而不使用它们的图像处理功能,例如edge()。我可以使用哪些方法/算法?任何论文/链接都很好(:
好吧,假设您的图像仅由黑色背景和里面的袋子组成,执行您要的内容的一种非常常见的方法是对图像进行阈值处理,然后找到所有白色像素的质心。
我进行了Google搜索,我能想到的最接近的东西与您想要的看起来像这样:
由于某种原因,该图像是RGB,即使它是灰度的,所以我们将其转换为灰度。我假设您不能使用任何内置的MATLAB函数,因此rgb2gray
消失了。尽管rgb2gray
实现了rgb2gray
标准,您仍然可以自己实现它。
一旦我们读入图像,您就可以对图像进行阈值处理,然后找到所有白色像素的质心。可以使用SMPTE Rec. 709确定行和列的位置为非零值,然后分别找到它们的均值。完成此操作后,我们可以显示图像并在形心所在的位置绘制一个红色圆圈。因此:
find
当我运行上面的代码时,这就是我们得到的:
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9zb0NWai5wbmcifQ==” alt =“在此处输入图像描述”>
不错!现在,您接下来要考虑的是处理多个对象的情况。如您所知,此代码仅检测一个对象。对于多个对象,我们将不得不做一些不同的事情。您需要做的是通过ID识别图像中的所有对象。这意味着我们需要创建一个ID矩阵,该矩阵中的每个像素都表示该对象所属的对象。之后,我们遍历每个对象ID并找到每个质心。这是通过为每个ID创建一个掩码,找到该掩码的质心并保存该结果来执行的。这就是所谓的find
查找。im = imread('http://ak.picdn.net/shutterstock/videos/3455555/preview/stock-footage-single-blank-gray-shopping-bag-loop-rotate-on-black-background.jpg');
%// Convert colour image to grayscale
im = double(im);
im = 0.299*im(:,:,1) + 0.587*im(:,:,2) + 0.114*im(:,:,3);
im = uint8(im);
thresh = 30; %// Choose threshold here
%// Threshold image
im_thresh = im > thresh;
%// Find non-zero locations
[rows,cols] = find(im_thresh);
%// Find the centroid
mean_row = mean(rows);
mean_col = mean(cols);
%// Show the image and the centroid
imshow(im); hold on;
plot(mean_col, mean_row, 'r.', 'MarkerSize', 18);
是在MATLAB中执行此操作的最常见方法,但是当您要自己实现此功能时,我将带您回到我前一段时间写的关于如何查找二进制图像的连接组件的文章:] >
请注意,该算法并不是最有效的算法,因此可能需要花费几秒钟的时间,但是我敢肯定您不介意等待:)现在让我们处理多个对象的情况。我也在Google上找到了这张图片:
我们将图像设置为正常阈值,然后将进行连接的分量分析,然后迭代每个标签并找到质心。但是,我要强制执行的另一个约束是我们将检查在连接的组件结果中找到的每个对象的区域。如果它小于某个数字,则意味着该对象可能归因于量化噪声,因此我们应跳过此结果。
因此,假设您在上面的链接文章中使用了代码,并将其放置在名为regionprops
的函数中,该函数具有以下原型:
How to find all connected components in a binary image in Matlab?
因此,将代码放在引用的文章中,然后将其放入带有函数头的名为的函数中,例如:
conncomptest
其中B = conncomptest(A);
是输入的二进制图像,conncomptest.m
是ID的矩阵,您将执行以下操作:
function B = conncomptest(A)
我们得到:
您可以使用出色的ImageMagick,它已安装在大多数Linux发行版中,并且可用于OS X,其他良好的操作系统和Windows。它包括
“ Connected Components”
像在命令行这样:
A
输出将是:
B
它显示6个对象,每行一个,并给出每个对象的边界框,质心和均值颜色。因此,第三行表示一个框,该框的宽度为299像素,高度为231像素,其左上角位于图像左上角的328处,而左上角为186像素。如果我在边界框中绘制,则可以在此处看到它们:
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9IZm82Ny5wbmcifQ==” alt =“在此处输入图像描述”>
也为您列出了质心。
上面命令的输出图像是这样的,显示每个形状以不同的灰色阴影阴影。请注意,最暗的一个变黑了,所以很难看到-几乎不可能:-)
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS90ZEJFby5wbmcifQ==” alt =“在此处输入图像描述”>“ >>
[正如您说的那样,您希望查看自己编写的连接的组件代码,可以在我的另一个答案中查看我的代码... im = imread('http://cdn.c.photoshelter.com/img-get2/I0000dqEHPhmGs.w/fit=1000x750/84483552.jpg');
im = double(im);
im = 0.299*im(:,:,1) + 0.587*im(:,:,2) + 0.114*im(:,:,3);
im = uint8(im);
thresh = 30; %// Choose threshold here
%// Threshold image
im_thresh = im > thresh;
%// Perform connected components analysis
labels = conncomptest(im_thresh);
%// Find the total number of objects in the image
num_labels = max(labels(:));
%// Find centroids of each object and show the image
figure;
imshow(im);
hold on;
for idx = 1 : num_labels
%// Find the ith object mask
mask = labels == idx;
%// Find the area
arr = sum(mask(:));
%// If area is less than a threshold
%// don't process this object
if arr < 50
continue;
end
%// Else, find the centroid normally
%// Find non-zero locations
[rows,cols] = find(mask);
%// Find the centroid
mean_row = mean(rows);
mean_col = mean(cols);
%// Show the image and the centroid
plot(mean_col, mean_row, 'r.', 'MarkerSize', 18);
end
无论如何,我希望这会有所帮助,您会把它看作是Ray已经提供的出色答案的补充。
您可以使用出色的ImageMagick,它已安装在大多数Linux发行版中,并且可用于OS X,其他良好的操作系统和Windows。它包括
“ Connected Components”