查找图像中对象的区域和颜色

时间:2017-08-13 19:42:35

标签: opencv image-processing scikit-image

我的图片看起来像这样:

tattoo of woman

我想弄清楚一些事情:

  1. 纹身的主要颜色是什么?
  2. 皮肤的主要颜色是什么?
  3. 纹身的面积(以像素为单位) - 在上面的纹身中,具体是什么?
  4. 我是图像处理的新手,但我的攻击计划是:

    1. 运行边缘检测
    2. 填写轮廓
    3. 将该图像的alpha设为具有纹身的alpha值
    4. width * height * % of white in alpha = area of tattoo ink
    5. 将alpha应用于原始图像并获取颜色分布,以某种方式给出答案,例如"此纹身中有黑色和红色"
    6. 反转alpha并将其应用于原始图像以获得肤色并找到平均色调
    7. 这是否是获得最终结果的合理方法?是否有一些我可能不知道的更容易/更可靠的东西,作为一个新手呢?

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

      tattoo of woman contour

      但我从这里遇到麻烦,用颜色填充轮廓以创建alpha。问题是我只想知道墨水的区域,而不是整个纹身的区域,所以这似乎更难填补轮廓

2 个答案:

答案 0 :(得分:3)

我没有使用边缘检测和轮廓,而是建议以下approch -

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

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

3)现在只需计算像素数量,即可获得纹身区域和皮肤。

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

答案 1 :(得分:1)

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

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)

tattoo

主要颜色的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