好吧,假设您的图像仅由黑色背景和其中的一个袋子组成,执行您所要求的操作的一种非常常见的方法是对图像进行阈值处理,然后找到所有白色像素的质心。
我做了一个谷歌搜索,我能想到的最接近你想要的东西看起来像这样:
http://ak.picdn.net/shutterstock/videos/3455555/preview/stock-footage-single-blank-gray-shopping-bag-loop-rotate-on-black-background.jpg
由于某种原因,这张图片是 RGB,尽管它是灰度的,所以我们将把它转换为灰度。我假设你不能使用任何内置的 MATLAB 函数,所以 rgb2gray 已经出局了。尽管rgb2gray 实现了SMPTE Rec. 709 标准,您仍然可以自己实现它。
读入图像后,您可以对图像进行阈值处理,然后找到所有白色像素的质心。这可以使用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);
当我运行上面的代码时,我们得到的是:
还不错!现在您的下一个问题是处理多个对象的情况。正如您已智能确定的那样,此代码仅检测到一个对象。对于多个对象的情况,我们将不得不做一些不同的事情。您需要做的是通过 ID 识别图像中的所有对象。这意味着我们需要创建一个 ID 矩阵,其中该矩阵中的每个像素表示该对象属于 哪个 对象。之后,我们遍历每个对象 ID 并找到每个质心。这是通过为每个 ID 创建一个掩码、找到该掩码的质心并保存此结果来执行的。这就是所谓的查找connected components。
regionprops 是在 MATLAB 中执行此操作的最常用方法,但由于您想自己实现此功能,我将把您推迟到我不久前写的关于如何找到二进制图像的连通分量的帖子:
How to find all connected components in a binary image in Matlab?
请注意,该算法不是最有效的算法,因此可能需要几秒钟,但我相信您不介意等待 :) 所以现在让我们处理多个对象的情况。我还在 Google 上找到了这张图片:
我们将图像作为正常阈值,然后不同的是执行连通分量分析,然后我们遍历每个标签并找到质心。但是,我要强制执行的另一个约束是,我们将检查在连接组件结果中找到的每个对象的区域。如果它小于某个数字,这意味着对象可能归因于量化噪声,我们应该跳过这个结果。
因此,假设您将上述链接帖子中的代码放入一个名为 conncomptest 的函数中,该函数具有以下原型:
B = conncomptest(A);
因此,将引用帖子中的代码放入一个名为conncomptest.m 的函数中,函数头如下:
function B = conncomptest(A)
其中A 是输入二值图像,B 是 ID 矩阵,您可以这样做:
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
我们得到: