Tranform HSV mask into a set of points
Clash Royale CLAN TAG#URR8PPP
Tranform HSV mask into a set of points
I created a HSV mask from the image. The result is like the following:
I hope that this mask can be represented by a set of points. My original idea was to use Skimage Skeletonize to create a line and then use the sliding window to calculate the local mean for point creation.
However, skeletonize takes too long. It requires 0.4s for each frame. This is not a good idea for video processing.
2 Answers
2
Do you want the points of all True elements of the mask, or do you just want a skeleton? If the former..
import skimage as ski
from skimage import io
import numpy as np
mask = ski.io.imread('./mask.png')[:,:,0]/255
mask = mask.astype('bool')
s0,s1 = mask.shape # dimensions of mask
a0,a1 = np.arange(s0),np.arange(s1) # make two 1d coordinate arrays
coords = np.array(np.meshgrid(a0,a1)).T # cartesian product into a coordinate matrix
coords = coords[mask] # mask out the points of interest
If the latter, you can get the start and end points (from left to right) of the object in the mask in a fast way with something like
start_mat = np.stack((np.roll(mask,1,axis=1),mask),-1)
start_mask = np.fromiter(map(lambda p: np.alltrue(p==np.array([False,True])),start_mat[mask]),dtype=bool)
starts = coords[start_mask]
end_mat = np.stack((np.roll(mask,-1,axis=1),mask),-1)
end_mask = np.fromiter(map(lambda p: np.alltrue(p==np.array([False,True])),end_mat[mask]),dtype=bool)
ends = coords[end_mask]
This will give you a rough outline of the object. Outline points will be missing anywhere that the slope of the figure is 0. You may have to think of a vertical difference scheme for those areas. The same idea would work with np.roll(...,axis=0)
. You could just concatenate the unique points from rolling over rows to the points from rolling over columns to get the full outline.
np.roll(...,axis=0)
Averaging the correct pairs to get the skeleton isn't so easy.
Here's a resultant outline. You can definitely make this faster than 0.4s:
Couldn't a simple For loop work?
Scan each "across" line of your bitmap looking for...
X pos where from Black
meets White
= new start point
.
from Black
White
start point
Also in same scanned line now look for a new X-pos:
where from White
meets Black
= new end point
.
from White
Black
end point
Either put dots at start/end points for "outline" effect,
or else put dots in "center" effect by dot.x = (end_point - start_point) / 2
dot.x = (end_point - start_point) / 2
I believe putting the dots at the center doesn't work quite like this VC. Think about what happens where the 'arm' meets the 'body' on the image provided by OP However if you can think of a way to get the skeleton from the start and end points, I showed a faster way than a for loop to get the start and end points in my answer
– kevinkayaks
Aug 23 at 19:37
Also this outline detection fails to give the points where the slope of the figure in the mask is 0. One has to difference in the y direction in those cases.
– kevinkayaks
Aug 23 at 19:44
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
1. this has nothing to do with HSV. 2. Vectorization is a slow process so unless you got some more info or restrictions on the scene (shapes , orientation complexity) then do not expect fast results ...
– Spektre
Aug 12 at 6:35