灰度分割/特征提取/斑点检测?

Bad*_*mer 2 matlab image-processing feature-extraction feature-detection image-segmentation

我试图找到一个起点,但我似乎无法找到正确的答案.我非常感谢你的指导.我也不知道正确的术语,因此标题.

  1. 我拍了一张背后有黑色背景的包.
  2. 我想提取袋子,类似于.
  3. 如果可能的话,找中心,像这样.

基本上,我希望能够提取像素blob然后找到中心点.

我知道这是两个不同的问题,但我想如果有人可以做后者,那么他们可以做第一个.我正在使用MATLAB,但想编写自己的代码而不使用像edge()这样的图像处理函数.我可以使用哪些方法/算法?任何论文/链接都会很好(:

ray*_*ica 9

好吧,假设你的图像只包含一个黑色背景和一个包里面,一个非常常见的方法来执行你所要求的是阈值图像,然后找到所有白色像素的质心.

我做了谷歌搜索,我能想到的最接近你想要的东西看起来像这样:

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);
Run Code Online (Sandbox Code Playgroud)

当我运行上面的代码时,这就是我们得到的:

在此输入图像描述

不错!现在您的下一个问题是处理多个对象的情况.正如您已明智地确定的那样,此代码仅检测一个对象.对于多个对象的情况,我们将不得不做一些不同的事情.您需要做的是通过ID识别图像中的所有对象.这意味着我们需要创建一个ID矩阵,其中该矩阵中的每个像素表示对象所属的对象.之后,我们遍历每个对象ID并找到每个质心.这是通过为每个ID创建一个掩码,找到该掩码的质心并保存该结果来执行的.这就是所谓的连接组件.

regionprops 这是在MATLAB中最常用的方法,但是你想自己实现这个,我会推荐你​​到我刚才写的关于如何找到二进制图像的连通组件的帖子:

如何在Matlab中找到二进制图像中的所有连通组件?

请注意,该算法不是最有效的,因此它可能需要几秒钟,但我确定你不介意等待:)所以让我们现在处理多个对象的情况.我还在Google上找到了这张图片:

http://cdn.c.photoshelter.com/img-get2/I0000dqEHPhmGs.w/fit=1000x750/84483552.jpg

我们将图像阈值设置为正常,然后将执行连接组件分析将会有所不同,然后我们遍历每个标签并找到质心.但是,我要强制执行的另一个约束是,我们将检查连接组件结果中找到的每个对象的区域.如果它小于某个数字,这意味着该对象可能归因于量化噪声,我们应该跳过这个结果.

因此,假设您在上面的链接帖子中获取了代码并将其放入一个函数中conncomptest,该函数具有以下原型:

B = conncomptest(A);
Run Code Online (Sandbox Code Playgroud)

因此,请参考引用的帖子中的代码,并将其放入conncomptest.m使用函数头调用的函数中,以便:

function B = conncomptest(A)
Run Code Online (Sandbox Code Playgroud)

A输入二进制图像在哪里,是BID的矩阵,你会做这样的事情:

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
Run Code Online (Sandbox Code Playgroud)

我们得到:

在此输入图像描述

  • 说真的,我得到的最好的答案.EVER. (2认同)