如何识别图像中的金色?

How to identify gold color in image?

我有一个关于硬币识别的作业。我国的硬币由两种颜色组成:金色和银色。如何识别金色?

我已经从包含少量硬币的图像中裁剪出每一枚硬币。我想知道如何鉴别金币。

我的讲师建议:

我的方法如下:

  1. 增强图像使颜色可见。
  2. 识别每个硬币并裁剪它们
  3. 确定他们的颜色并将他们分成两组:银色和金色。
  4. 通过从每种颜色制作一枚硬币作为参考来确定它们的价值,然后将另一枚硬币与参考硬币进行比较(基于比率)。

我已经完成了第 1 步和第 2 步,但我卡在了第三步。我不知道如何区分金色和银色硬币。我应该使用哪种方法在 MATLAB 中区分它们?

使用 imagemagick 库:

Fuzz 运算符可让您将图像颜色与特定颜色进行比较。虽然它们不必完全相同,但具有您决定的相似系数。所以算法可以是下面的:

  1. 检测图像中的金色(模糊检测)
  2. 将所有金色像素替换为黑色(可以是任何颜色)
  3. 计算新图像中的黑色像素
  4. 如果至少有80%的像素都被统计过,则为金币,否则不是金币:

将金色转换为黑色:

 convert img -fuzz 80%  -fill black -opaque gold  newImage

获得所有不同的颜色计数:

convert  newimage -define histogram:unique-colors=true \
        -format %c histogram:info:-

如果黑色计数在80%以上(+-),则为金币。

*一定要select一个不能在原始图像中的替换颜色。

这里有一些可以使用的东西。它仅针对此特定图像进行了调整,可能不适用于其他图像。

  1. 使用 gamma = 1.5 执行伽马校正。之所以这样做是因为我想将图像右侧较亮的金币强度调低以匹配左侧图像上的金币,以便更容易进行阈值和分割。

  2. 使用色调和饱和度通道阈值出金币

  3. 使用形态学并填充阈值结果具有的任何孔洞

  4. 删除所有面积小于 12000 像素的块。


第 1 步

您可以使用 imadjustgamma = 1.5 执行伽马调整,您只需执行以下操作。首先加载我将直接从 Whosebug 执行的图像,然后进行伽玛调整:

close all;
im = imread('http://i.stack.imgur.com/g4FCV.jpg');
im_enhance = imadjust(im, [], [], 1.5);

im是原图,im_enhance是增强后的图。我们得到如下增强图像:

有点难看,但是如果你点击上面的图片自己放大图片,你会看到图片右边的金色比以前稍微深一些。

第 2 步

首先使用 rgb2hsv:

将您的图像转换为 HSV
hsv = rgb2hsv(im2double(im_enhance));

之后,我使用 impixelinfo 打开上图,执行 imshow(im_enhance) 并将鼠标悬停在金币上以查看色相和饱和度。通过检查,我看到色调值大约为 0.25 或更小,饱和度值大约为 0.25 或更大,以区分金币和银币。因此,使用这些范围作为阈值并得到一个二进制映射,告诉您什么属于金币,什么不属于:

gold_coins = hsv(:,:,1) < 0.25 & hsv(:,:,2) > 0.25;

我们现在得到这张图片:

不完美。我们可以看到大块白色的是金币,有洞的是银币。

第 3 步

我们接下来要做的是填充黄金对象必须的任何孔,以确保您获得所有应该是黄金的区域。使用 imfill'holes' 选项来执行此操作。

gold_coins_fill = imfill(gold_coins, 'holes');

我们现在得到:

太好了,但我们又要处理银币了。金币完全没问题

第 4 步

为了移除任何属于银币的质量,我移除了蒙版中所有小于 12000 像素的区域。这是通过反复试验完成的。您可以使用函数 bwareaopen 并将 12000 指定为此图像上的第二个参数:

gold_coins_final = bwareaopen(gold_coins_fill, 12000);

我们现在得到:


如果你只想通过复制和粘贴运行,完整代码如下所示:

% Step #1
close all;
im = imread('http://i.stack.imgur.com/g4FCV.jpg');
im_enhance = imadjust(im, [], [], 1.5);

% Step #2
hsv = rgb2hsv(im2double(im_enhance));   
gold_coins = hsv(:,:,1) < 0.25 & hsv(:,:,2) > 0.25;

% Step #3
gold_coins_fill = imfill(gold_coins, 'holes');

% Step #4
gold_coins_final = bwareaopen(gold_coins_fill, 12000);
imshow(gold_coins_final);