Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Convexity Defects #55

Open
ashwani-rathee opened this issue Jan 15, 2022 · 0 comments
Open

[Feature Request] Convexity Defects #55

ashwani-rathee opened this issue Jan 15, 2022 · 0 comments

Comments

@ashwani-rathee
Copy link
Member

I was trying to do hand gesture recogniton and convexity defects seemed a pretty resonable to do that with classic image processing but we didn't have a implementation for this(OpenCV does) so using what we have currently,I wrote this implementation:

using LazySets, StaticArrays
function findconvexitydefects(
	contour, 
	convhull;
	dist=1.1,
	absdiff=10, 
	mindist=0,
	currsize= 50 )
	# first we need to match our contours and our convehull regions
	numindices = []
	previous = 0
	for i in convhull
		for (num,j) in enumerate(contour) 
			if norm(Tuple(i) .- Tuple(j)) < dist && abs(previous-num) > absdiff # to avoid small and very close regions
					push!(numindices, num)
					previous = num
				break
			end
		end
	end
	# we want the numindices same as our convhull points, 
	# to define regions of interest for each convhull line
	
	defects = Vector{CartesianIndex{2}}([]) # indexes with defects

	# incase numndices < convhull indexes, 
	# meaning we don't hv regions for all lines
	if size(numindices)[1] < size(convhull)[1] 
		throw(error("Raise the range dist, numindices points less than convexhull points, $(size(numindices)[1])"))
	end

	# iterate over each consecutive pair of convhull points to form line
	for i in 1:size(convhull)[1]-1
		# to handle the case where numindices are like 1256, then 1
		if numindices[i] > numindices[i+1]
			curr = vcat(contour[numindices[i]: end], contour[1: numindices[i+1]])
		else
			# general case to define contours poins for each convhull region
			curr = contour[numindices[i]:numindices[i+1]]
		end

		# to remove minor regions of contours, we can set currsize
		if size(curr)[1] < currsize
			continue
		end

		# Defining the line		
		p1 = Float64.(Tuple(convhull[i]))  # point 1
		p2 = Float64.(Tuple(convhull[i+1])) # point 2
		line = Line(;from=[p1[1], p1[2]], to=[p2[1], p2[2]])

		maxdef = 0 # max distance from our convhull line
		defloc = CartesianIndex(0,0) # location of the that point

		# check for each contour point in a convhull region
		# their distance and find max distance point
		for j in curr
			p = SA[j[1], j[2]]
			lpdist = distance(p, line) # find distance
			# update if we find new max
			if lpdist > maxdef
				maxdef = lpdist
				defloc = j
			end
		end
		# we can define what minimum distance from line should be
		if maxdef > mindist
			push!(defects, defloc)
		end
	end
	return defects
end

Issue that can be solved is I think synchronise convehull and contours points to remove the first loop am not sure if we have a proper findcontours/bwboundaries in juliaimages but I used suzuki and abe algorithm exampe provided by archit rungta

We want to find the blue points which are away from convexhull. I thought given that convexhull(in ImageMorphology.jl) uses a binary mask, so it must be finding the boundaries/contours somehow, so maybe we can use that(avoid contour calc 1 time) but then it only uses partial part of the boundaries using the getboundarypoints() function(rightmost image)
Images:

MRE

using Images, ImageDraw
img = Gray.(load("img592.png"))
img = mapwindow(ImageFiltering.median, dilate(dilate(dilate(dilate(img)))), (15, 15))
contours = find_contours(img) # https://juliaimages.org/v0.22/democards/examples/contours/contour_detection/
convhull = convexhull(img .> 0.5)
push!(convhull, convhull[1])

function drawdots!(img, res, color )
	for i in res
		img[i[1]-10:i[1]+10, i[2]-10:i[2]+10] .= color
	end
end

res = findconvexitydefects(contours[1], convhull; dist=3, absdiff = 1, currsize= 80, mindist =10)
img_convex1 = RGB{N0f8}.(ones(size(img)))
drawdots!(img_convex1, res, RGB(0,0,1))
draw!(img_convex1, ImageDraw.Path(convhull), RGB(0))
draw_contours(img_convex1, RGB(0), contours) # again availble in archit tut
[img img_convex1]

Would love to have this in here and have a discussion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant