Reputation: 97
I have an image that looks like this:
And I want to figure out a couple of things:
I'm new to image processing but my plan of attack is something like:
width * height * % of white in alpha = area of tattoo ink
Does this seem like a sensible approach to get the end result? Is there something easier / more reliable that I might not know, being a novice to this?
I ran some edge analysis code against it using skimage
and got a contour like this:
But I'm having trouble from here to fill in the contour with a colour to create an alpha. The problem is that I only want to know the area of the ink, not of the entire tattoo, so this seems harder to fill in the contour
Upvotes: 3
Views: 1766
Reputation: 13733
An alternative approach would consist in performing color quantization through k-means clustering. The tattoo shown in the provided example has only one color, therefore the quantized image should have two colors, namely ink and skin.
import numpy as np
from skimage import io
from sklearn.cluster import KMeans
img = io.imread('https://i.sstatic.net/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)
The RGB coodinates of the predominant colors are:
In [69]: centers
Out[69]:
array([[ 226.44193236, 193.24337359, 175.1311746 ],
[ 40.0549615 , 36.64523871, 40.75754915]])
Assuming that the ink is darker than the skin (i.e. the Euclidean norm of the ink color is smaller than that of the skin), the proportion of image pixels covered by the tattoo can be computed like this:
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
Upvotes: 1
Reputation: 398
Instead of using edge detection and contours, I'll suggest the following approch-
1) Convert image from RGB to grayscale.
2) Use adaptive threasholding to convert it into a binary image (I'm suggesting this after looking at the image that you have uploaded).
3) Now simply by counting the number of pixels, you can get the area of tattoo and the skin.
4) To calculate the predominant colors(of which I only see two here), you can either just go for the average of all pixels corresponding to the tattoo and skin from the binary image, or you can compute a color histogram.
Upvotes: 3