I'd like to detect lines inside a region of interest. My output image should display the original image and the detected lines in the selected ROI. So far it has not been a problem to find lines in the original image or select a ROI but finding lines only inside the ROI did not work. My MWE reads an image, converts it to grayscale and lets me select a ROI but gives an error when HoughLinesP
wants to read roi
.
import cv2
import numpy as np
img = cv2.imread('example.jpg',1)
gray = cv2.cvtColor(img ,cv2.COLOR_BGR2GRAY)
# Select ROI
fromCenter = False
roi = cv2.selectROI(gray, fromCenter)
# Crop ROI
roi = img[int(roi[1]):int(roi[1]+roi[3]), int(roi[0]):int(roi[0]+roi[2])]
# Find lines
minLineLength = 100
maxLineGap = 30
lines = cv2.HoughLinesP(roi,1,np.pi/180,100,minLineLength,maxLineGap)
for x in range(0, len(lines)):
for x1,y1,x2,y2 in lines[x]:
cv2.line(img,(x1,y1),(x2,y2),(237,149,100),2)
cv2.imshow('Image',img)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
The console shows:
lines = cv2.HoughLinesP(roi,1,np.pi/180,100,minLineLength,maxLineGap)
error: OpenCV(3.4.1) C:\Miniconda3\conda-bld\opencv-suite_1533128839831\work\modules\imgproc\src\hough.cpp:441: error: (-215) image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) in function cv::HoughLinesProbabilistic
My assumption is that roi
does not have the correct format. I am using Python 3.6 with Spyder 3.2.8.
Thanks for any help!
The function cv2.HoughLinesP
is expecting a single-channel image, so the cropped region could be taken from the gray image and that would remove the error:
# Crop the image
roi = list(map(int, roi)) # Convert to int for simplicity
cropped = gray[roi[1]:roi[1]+roi[3], roi[0]:roi[0]+roi[2]]
Note that I'm changing the output name from roi
to cropped
, and that's because you're going to still need the roi
box. The points x1
, x2
, y1
, and y2
are pixel positions in the cropped image, not the full image. To get the images drawn correctly, you can just add the upper left corner pixel position from roi
.
Here's the for loop with relevant edits:
# Find lines
minLineLength = 100
maxLineGap = 30
lines = cv2.HoughLinesP(cropped,1,np.pi/180,100,minLineLength,maxLineGap)
for x in range(0, len(lines)):
for x1,y1,x2,y2 in lines[x]:
cv2.line(img,(x1+roi[0],y1+roi[1]),(x2+roi[0],y2+roi[1]),(237,149,100),2)