查找图像中对象的面积和颜色

Finding the area and colours of an object in an image

我有一张看起来像这样的图片:

我想弄清楚几件事:

  1. 纹身的主要颜色是什么?
  2. 皮肤的主要颜色是什么?
  3. 上面纹身的纹身面积(以像素为单位)是多少?

我是图像处理的新手,但我的攻击计划是这样的:

  1. 运行边缘检测
  2. 填充轮廓
  3. 采用该图像的 alpha 得到纹身的 alpha
  4. width * height * % of white in alpha = area of tattoo ink
  5. 将 alpha 应用于原始图像并获取颜色分布,以某种方式给出类似 "this tattoo has black and red in it"
  6. 的答案
  7. 反转 alpha 并将其应用于原始图像以获取肤色并找到平均色调

这看起来是获得最终结果的明智方法吗?作为新手,有没有我可能不知道的更简单/更可靠的东西?

我 运行 使用 skimage 对它进行了一些边缘分析代码,得到了这样的轮廓:

但是我在使用颜色填充轮廓以创建 alpha 时遇到了问题。问题是我只想知道 墨水 的面积,而不是整个纹身的面积,所以这似乎更难填充轮廓

我不使用边缘检测和轮廓,而是建议使用以下方法-

1) 将图像从 RGB 转换为灰度。

2) 使用自适应阈值将其转换为二进制图像(我在查看您上传的图像后建议这样做)。

3)现在只要简单的计算像素点的个数,就可以得到纹身和皮肤的面积。

4) 要计算主要颜色(我在这里只看到两种颜色),您可以从二值图像中求出与纹身和皮肤对应的所有像素的平均值,或者您可以计算颜色直方图。

另一种方法是通过 k 均值聚类执行 颜色量化。所提供示例中的纹身只有一种颜色,因此量化后的图像应该有两种颜色,即墨水和皮肤。

import numpy as np
from skimage import io
from sklearn.cluster import KMeans

img = io.imread('https://i.stack.imgur.com/Upcb0.png')
n_colors = 2

X = img.reshape((-1, 3))
kmeans = KMeans(n_clusters=n_colors, random_state=0).fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
quantized = centers[labels].reshape(img.shape).astype('uint8')

io.imshow(quantized)

主要颜色的 RGB 坐标是:

In [69]: centers
Out[69]: 
array([[ 226.44193236,  193.24337359,  175.1311746 ],
       [  40.0549615 ,   36.64523871,   40.75754915]])

假设墨水比皮肤深(即墨水颜色的欧几里得范数小于皮肤的欧几里德范数),纹身覆盖的图像像素比例可以这样计算:

In [70]: darkest = np.argmin(np.sqrt(np.sum(centers**2, axis=1)))

In [71]: np.true_divide(np.sum(labels == darkest), labels.size)
Out[71]: 0.24738437499999999