I'm trying to write the code for SLAM using OpenCV from scratch. While I'm trying to show detected features from each frame in colored-circular mark, I've got a problem showing this in color.
Summary
goodFeaturesToTrack
function, cv2.cvtColor(img, cv2.BGR2GRAY)
process should be done first.goodFeaturesToTrack
process, I've tried to indicate features in colored circle in frame.cv2.GRAY2BGR
I expected colored circular marks in the frame but this is not currently being seen.
#! /usr/bin/env python3
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
W = 1920//2
H = 1080//2
def process(image):
image = cv.resize(image,(W,H))
image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(image, 3000, 0.01, 3)
corners = np.int0(corners)
image_copy = cv.cvtColor(image, cv.COLOR_GRAY2BGR)
for i in corners:
x, y = i.ravel()
cv.circle(image_copy, (x,y), color = (0,0,255), radius=3)
#cv.circle(image, (x,y), 3, 255, -1)
return image_copy
if __name__ == "__main__":
cap = cv.VideoCapture("../test/test_countryroad.mp4")
while cap.isOpened():
ret, frame = cap.read()
if ret == True:
frame = process(frame)
frame = cv.cvtColor(frame, cv.COLOR_GRAY2RGB)
cv.imshow('frame', frame)
if cv.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv.destroyAllWindows()
But the error comes out like below after I run this code.
Traceback (most recent call last):
File "./slam.py", line 34, in <module>
frame = cv.cvtColor(frame, cv.COLOR_GRAY2RGB)
cv2.error: OpenCV(4.2.0) /home/hkim/opencv/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<1>; VDcn = cv::impl::{anonymous}::Set<3, 4>; VDepth = cv::impl::{anonymous}::Set<0, 2, 5>; cv::impl::{anonymous}::SizePolicy sizePolicy = (cv::impl::<unnamed>::SizePolicy)2; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
> 'VScn::contains(scn)'
> where
> 'scn' is 3
How can I fix it?
Your image is grayscale and thus when you are trying to draw coloured circles in the image, you can't as there is only one channel as opposed to the expected three for colour images. What you need to do is create a separate copy of the frame so you can run the interest point detection on that, get the corners and draw them on the colour version of the image instead.
def process(image):
image = cv.resize(image,(W,H))
# Change
image_copy = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# Change
corners = cv.goodFeaturesToTrack(image_copy, 3000, 0.01, 3)
corners = np.int0(corners)
for i in corners:
x, y = i.ravel()
cv.circle(image, (x,y), color = (0,0,255), radius=3)
return image
Finally in your while
loop, because the image is now in colour, you can remove the conversion statement from grayscale to colour as the function returns the image already in colour.
while cap.isOpened():
ret, frame = cap.read()
if ret == True:
frame = process(frame)
# Remove the line below
# frame = cv.cvtColor(frame, cv.COLOR_GRAY2RGB)
cv.imshow('frame', frame)
if cv.waitKey(1) & 0xFF == ord('q'):
break
else:
break