-1

Hello I am beginner in OpenCv. I have a maze image. I wrote maze solver code. I need to get the photo like the picture for this code to work. I want to choose the contours of the white area using ROI but I could not

When I try the ROI method I get a smooth rectangle with a black area selected.

https://i.stack.imgur.com/Ty5BX.png -----> this is my code result

https://i.stack.imgur.com/S7zuJ.png --------> I want to this result

import cv2
import numpy as np

#import image
image = cv2.imread('rt4.png')

#grayscaleqq
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#cv2.imshow('gray', gray)
#qcv2.waitKey(0)

#binary
#ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
threshold = 150
thresh = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY)[1]
cv2.namedWindow('second', cv2.WINDOW_NORMAL)
cv2.imshow('second', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

#dilation
kernel = np.ones((1,1), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)
cv2.namedWindow('dilated', cv2.WINDOW_NORMAL)
cv2.imshow('dilated', img_dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()




#find contours
im2,ctrs, hier = cv2.findContours(img_dilation.copy(), 
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)


#sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr) 
[0])

list = []

for i, ctr in enumerate(sorted_ctrs):
# Get bounding box
x, y, w, h = cv2.boundingRect(ctr)

# Getting ROI
roi = image[y:y+h, x:x+w]

a = w-x
b = h-y
list.append((a,b,x,y,w,h))


# show ROI
#cv2.imshow('segment no:'+str(i),roi)
cv2.rectangle(image,(x,y),( x + w, y + h ),(0,255,0),2)
#cv2.waitKey(0)

if w > 15 and h > 15:
    cv2.imwrite('home/Desktop/output/{}.png'.format(i), roi)

cv2.namedWindow('marked areas', cv2.WINDOW_NORMAL)
cv2.imshow('marked areas',image)
cv2.waitKey(0)
cv2.destroyAllWindows()




gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)
dst = cv2.cornerHarris(gray,2,3,0.04)

#result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None)


image[dst>0.01*dst.max()]=[0,0,255]

cv2.imshow('dst',image)
if cv2.waitKey(0) & 0xff == 27:
cv2.destroyAllWindows()

list.sort()
print(list[len(list)-1])

2 Answers2

0

A simple solution to just draw a slanted rectangle would be to use cv2.polylines. Based on your result, I'm assuming you have the coordinates of the vertices of the area already, lets call them [x1,y1], [x2,y2], [x3,y3], [x4,y4]. The polylines function draws a line from vertex to vertex to create a closed polygon.

import cv2
import numpy as np

#List coordinates of vertices as an array
pts = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]], np.int32)
pts = pts.reshape((-1,1,2))

#Draw lines from vertex to vertex
cv2.polylines(image, [pts], True, (255,0,0))
J. Chow
  • 1
  • 1
  • hi, First of all thank you for your reply. I do not have corner points. I just have ROI rectangle points and I do not know how to get the corner points. I am a beginner opencv. Do you know how to get ? – ömer ali erdemir Sep 15 '18 at 06:44
0

I misunderstood your question earlier. So, I'm rewriting.

As @Silencer has already stated, you could use the drawContours method. You can do it as follows:

import cv2
import numpy as np

#import image
im = cv2.imread('Maze2.png')
gaus = cv2.GaussianBlur(im, (5, 5), 1)
# mask1 = cv2.dilate(gaus, np.ones((15, 15), np.uint8, 3))
mask2 = cv2.erode(gaus, np.ones((5, 5), np.uint8, 1))
imgray = cv2.cvtColor(mask2, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

maxArea1=0
maxI1=0

for i in range(len(contours)):
    area = cv2.contourArea(contours[i])
    epsilon = 0.01 * cv2.arcLength(contours[i], True)
    approx = cv2.approxPolyDP(contours[i], epsilon, True)
    if area > maxArea1 :
        maxArea1 = area

print(maxArea1)
print(maxI1)
cv2.drawContours(im, contours, maxI1, (0,255,255), 3)

cv2.imshow("yay",im)
cv2.imshow("gray",imgray)
cv2.waitKey(0)

cv2.destroyAllWindows()

I used it on the following image: enter image description here And I got the right answer. You can add additional filters, or you could decrease the area using an ROI, to decrese the discrepancy, but it wasn't required

Hope it helps!

Eshita Shukla
  • 791
  • 1
  • 8
  • 30