Quantcast
Channel: OpenCV Q&A Forum - Latest question feed
Viewing all articles
Browse latest Browse all 19555

Clicking on a point in an image finds the closest contour points

$
0
0
**Update: As suggested. I added my current code that detects all boundaries of each shape (not desired) with another problem that these boundary lines can be a few pixels wide and form inside and outside countour to be recognized** Let say I click on a point inside wanted3 shape/contour (see second image). I would use C#.net OpenCV 2 and/or 3 One Note. The lines denoting shapes can be one or more pixel wide. I would like the recognized points to lay exactly in the middle of that line, so when I do another recognition of surrounding shape I will get an exact point for that shared line recognized in 2 contours ![image description](http://i.stack.imgur.com/fmpw6.jpg) **I want the closest contour recognized, that encompasses the pressed point with a mouse left click within it. There can however be a larger encompassing contour (not shown here; think of it as a county encompassing cities/places), and I just want the closest one recognized.** ![image description](/upfiles/14612166759855551.jpg) **Whan I press inside wanted2 shape I want South-East border to have exactly the same discoverer contour points as wanted3 no matter how thick the bordering line is (so some calculation of where the middle point is necessaryl Thanks Rad** Sub ProcessImageAndUpdateGUI(sender As Object, arg As EventArgs) Try If (rdoImageFile.Checked = True) Then 'if the image file radio button is chosen . . . Try imgOriginal = New Image(Of Bgr, Byte)(txtFile.Text) 'get original image from file name in text box Catch ex As Exception Return End Try ElseIf (rdoWebcam.Checked = True) Then 'else if the webcam radio button is chosen . . . Try imgOriginal = capWebcam.QueryFrame() 'get next frame from webcam Catch ex As Exception Return End Try Else 'should never get here End If If (imgOriginal Is Nothing) Then 'if imgOriginal is null Return 'bail End If 'perform image smoothing imgSmoothed = imgOriginal.PyrDown().PyrUp() 'Gaussian pyramid decomposition imgSmoothed._SmoothGaussian(3) 'Gaussian smooth, argument is size of filter window If (ckFilterOnColor.Checked = True) Then 'if filter on color check box is checked, then filter on color imgGrayColorFiltered = imgSmoothed.InRange(New Bgr(dblMinBlue, dblMinGreen, dblMinRed), New Bgr(dblMaxBlue, dblMaxGreen, dblMaxRed)) imgGrayColorFiltered = imgGrayColorFiltered.PyrDown().PyrUp() 'repeat smoothing process after InRange function call, imgGrayColorFiltered._SmoothGaussian(3) 'seems to work out better this way ElseIf (ckFilterOnColor.Checked = False) Then 'if filter on color is not checked, imgGrayColorFiltered = imgSmoothed.Convert(Of Gray, Byte)() 'then convert to gray without filtering End If 'Dim grayCannyThreshold As Gray = New Gray(160) 'first Canny threshold, used for both circle detection, and line / triangle / rectangle detection 'Dim grayCannyThreshold As Gray = New Gray(200) 'first Canny threshold, used for both circle detection, and line / triangle / rectangle detection Dim grayCannyThreshold As Gray = New Gray(240) 'first Canny threshold, used for both circle detection, and line / triangle / rectangle detection Dim grayCircleAccumThreshold As Gray = New Gray(100) 'second Canny threshold for circle detection, higher number = more selective Dim grayThreshLinking As Gray = New Gray(80) 'second Canny threshold for line / triangle / rectangle detection 'imgCanny = imgGrayColorFiltered.Canny(grayCannyThreshold, grayThreshLinking) 'Canny image used for line, triangle, rectangle, and polygon detection imgCanny = imgGrayColorFiltered.ThresholdBinary(grayCannyThreshold, New Gray(255)) imgCircles = imgOriginal.CopyBlank() 'create blank image, use for circles later imgLines = imgOriginal.CopyBlank() 'create blank image, use for lines later imgTrisRectsPolys = imgOriginal.CopyBlank() 'create blank image, use for triangles and rectangles later 'HoughCircles arguments Dim dblAccumRes As Double = 2.0 'resulution of the accumulator used to detect centers of circles Dim dblMinDistBetweenCircles As Double = imgGrayColorFiltered.Height / 4 'min distance between centers of detected circles Dim intMinRadius As Integer = 10 'min radius of circles to search for Dim intMaxRadius As Integer = 400 'max radius of circles to search for 'find circles Dim circles As CircleF() = imgGrayColorFiltered.HoughCircles(grayCannyThreshold, grayCircleAccumThreshold, dblAccumRes, dblMinDistBetweenCircles, intMinRadius, intMaxRadius)(0) For Each circle As CircleF In circles imgCircles.Draw(circle, New Bgr(Color.Red), 2) 'draw circles on circles image If (ckDrawCirclesOnOriginalImage.Checked = True) Then 'if check box is checked imgOriginal.Draw(circle, New Bgr(Color.Red), 2) 'then also draw circles on original image End If Next 'HoughLinesBinary arguments Dim dblRhoRes As Double = 1.0 'distance resolution in pixels Dim dblThetaRes As Double = 4.0 * (Math.PI / 180.0) 'angle resolution in radians (multiply by PI / 180 converts to radians) Dim intThreshold As Integer = 20 'a line is returned by the function if the corresponding accumulator value is greater than threshold Dim dblMinLineWidth As Double = 30.0 'minimum width of a line Dim dblMinGapBetweenLines As Double = 10.0 'minimum gap between lines 'find lines Dim lines() As LineSegment2D = imgCanny.HoughLinesBinary(dblRhoRes, dblThetaRes, intThreshold, dblMinLineWidth, dblMinGapBetweenLines)(0) For Each line As LineSegment2D In lines imgLines.Draw(line, New Bgr(Color.DarkGreen), 2) 'draw lines on lines image If (ckDrawLinesOnOriginalImage.Checked = True) Then 'if check box is checked imgOriginal.Draw(line, New Bgr(Color.DarkGreen), 2) 'then also draw lines on original image End If Next Dim lstTriangles As List(Of Triangle2DF) = New List(Of Triangle2DF)() 'declare list of triangles Dim lstRectangles As List(Of MCvBox2D) = New List(Of MCvBox2D)() 'declare list of "rectangles" Dim lstPolygons As List(Of Contour(Of Point)) = New List(Of Contour(Of Point)) 'declare list of polygons Dim i1 = 0 Mod 2 '0 Dim i2 = 1 Mod 2 '1 Dim i3 = 2 Mod 2 '0 Dim i4 = 3 Mod 2 '1 Dim i5 = 4 Mod 2 '0 'Dim contours As Contour(Of Point) = imgCanny.FindContours() 'find a sequence (similar to a linked list) of contours using the simple approximation method Dim i = 0 Using storage As New MemStorage Dim contours1 As Contour(Of Point) = imgCanny.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage) Dim contours As Contour(Of Point) = imgCanny.FindContours() While contours IsNot Nothing ' And CvInvoke.cvCheckContourConvexity(contours) = 0 Dim currentContour As Contour(Of Point) = contours.ApproxPoly(contours.Perimeter * 0.0015, storage) ' 0.0015 za Kragujevac1.jpg - 76 points If currentContour.BoundingRectangle.Width > 20 Then 'CvInvoke.cvDrawContours(color, contours, New MCvScalar(255), New MCvScalar(255), -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, New Point(0, 0)) 'color.Draw(currentContour.BoundingRectangle, New Bgr(0, 255, 0), 1) End If 'http://stackoverflow.com/questions/33715981/emgucv-findcontours-how-to-get-the-points-themselves For Each point As Point In currentContour.ToArray() 'https://github.com/AnthonyNystrom/Pikling/blob/f58082b0be767994ea09e64613b83eea3e9b1497/Server/Emu-CV/Emgu.CV.SourceAndExample-1.5.0.1/src/Emgu.CV/Seq.cs 'if i Mod 2 = 1 then imgCanny.Draw(New Rectangle(point.X, point.Y, 4, 4), New Gray(100), 0) 'end if Next i += 1 contours = contours.HNext End While End Using

Viewing all articles
Browse latest Browse all 19555

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>