Draw lines on a field

asked 2018-09-14 07:52:31 -0600

danieltak gravatar image

updated 2018-09-14 11:37:39 -0600

With this image:

colored field

A threshold was applied:

threshold

And the expected result would be:

Expected Result

With the following code being used and this tutorial and this function:

import cv2
import numpy as np

kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))

def find_skeleton3(img):
    # https://stackoverflow.com/a/42846932/7690982
    skeleton = np.zeros(img.shape,np.uint8)
    eroded = np.zeros(img.shape,np.uint8)
    temp = np.zeros(img.shape,np.uint8)

    retval,thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))

    iters = 0
    while(True):
        cv2.erode(thresh, kernel, eroded)
        cv2.dilate(eroded, kernel, temp)
        cv2.subtract(thresh, temp, temp)
        cv2.bitwise_or(skeleton, temp, skeleton)
        thresh, eroded = eroded, thresh # Swap instead of copy

        iters += 1
        if cv2.countNonZero(thresh) == 0:
            return (skeleton,iters)

img = cv2.imread('C:\\Users\\Desktop\\teste\\1.jpg')
#HSV
#https://stackoverflow.com/a/47483966/7690982
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (36, 0, 0), (70, 255,255))
## slice no verde
imask = mask>0
verde = np.zeros_like(img, np.uint8)
verde[imask] = img[imask]
cv2.imwrite('C:\\Users\\Desktop\\teste\\2.jpg', verde)

#Threshold
(canal_h, canal_s, canal_v) = cv2.split(verde)
retval, threshold = cv2.threshold(canal_v, 130, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imwrite('C:\\Users\\Desktop\\teste\\3.jpg', canal_v)

#Hough
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(threshold,1,np.pi/180,255,minLineLength,maxLineGap)
img = np.ones((3000,4000,3), np.uint8)
img[img==1]=255
for x in range(0, len(lines)):
    for x1,y1,x2,y2 in lines[x]:
        cv2.line(img,(x1,y1),(x2,y2),(0,0,0),15)
cv2.imwrite('C:\\Users\\Desktop\\teste\\4.jpg', img)

#Skeletonize
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
esqueleto, iters = find_skeleton3(img)
esqueleto =  cv2.dilate(esqueleto,kernel,iterations = 4)
cv2.imwrite('C:\\Users\\Desktop\\teste\\5.jpg', esqueleto)

The result is:

Result

What would be the best approach to solve this?

Multiple Ransac? Hough Transform? Maybe reduce the size of the blobs?

edit retag flag offensive close merge delete

Comments

1

A linear Hough transform would be a good idea to try.

A directional diffusion (Perona&Malik) could help to clean up the lines.

Another idea that comes to my head would be a fourier transform. It should have a maximum in the direction and frequency of the lines.

kbarni gravatar imagekbarni ( 2018-09-15 16:27:45 -0600 )edit