Error, while opening Numpy array in OpenCV

Question:

I am currently stuck on detecting the hough lines in a precalculated NumPy array.
However, it seems like I cannot figure out, why OpenCV doesn’t accept the NumPy array to work with and detect the lines.
The error message refers to the input channels, even so, I thought this should be detected automatically since OpenCV uses NumPy arrays natively.

I provided a minimum working example below.
However, the line detection might fail because of the random values.

import numpy as np
import cv2
from matplotlib import pyplot as plt

format = 50
img = np.random.choice([0, 1], size=(format,format), p=[1/30, 29/30])
plt.imshow(img, interpolation='nearest')
plt.show()

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize = 3)
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap)
for x1,y1,x2,y2 in lines[0]:
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imshow('image',img)
cv2.waitKey(0)

Error Message:

> cv2.error: OpenCV(4.2.0)
> ../modules/imgproc/src/color.simd_helpers.hpp:92: error:
> (-2:Unspecified error) in function
> 'cv::impl::{anonymous}::CvtHelper<VScn, VDcn, VDepth,
> sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with
> VScn = cv::impl::{anonymous}::Set<3, 4>; VDcn =
> cv::impl::{anonymous}::Set<1>; VDepth = cv::impl::{anonymous}::Set<0,
> 2, 5>; cv::impl::{anonymous}::SizePolicy sizePolicy =
> cv::impl::<unnamed>::NONE; cv::InputArray = const cv::_InputArray&;
> cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
> 'VScn::contains(scn)'
> where
> 'scn' is 1

Edit:
I know the problem is with the numpy array being of binary data (0 or 1), but I don’t know how to read it in to be handled properly.

Asked By: fynn

||

Answers:

As written in the comments there are several flaws in your code.

  • Use an image size where Houghline has a chance to find lines.
  • For an image the np.random.choise array has to be converted to unit8.
  • The result can be used as grayscale image.
  • The colour "white" in grayscale image has value 255.
  • If you want to draw colours, you have to convert your image to BGR.
  • White noise will hardly lead to detected lines. I have intentionally drawn a line through the noise to demonstrate, that houghlines can distinguish this line from the noise.

You can use this working example to start from and edit it step by step to what you actually want to do.

import numpy as np
import cv2


f = 500
img = np.random.choice([255, 0], size=(f, f), p=[1/30, 29/30]).astype("uint8")
cv2.line(img, (50, 50), (100, 300), 255, 2)

cv2.imshow('image', img)
cv2.waitKey(0)

minLineLength = 100
maxLineGap = 40
lines = cv2.HoughLinesP(img, 1, np.pi/180, 100, minLineLength, maxLineGap)

img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

if lines is not None:
    for x1, y1, x2, y2 in lines[0]:
        cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

cv2.imshow('image', img)
cv2.waitKey(0)

Output:

enter image description here

Answered By: Markus
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.