Frames are not seen in BGR scale (OpenCV)

316 views Asked by At

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

  • For goodFeaturesToTrack function, cv2.cvtColor(img, cv2.BGR2GRAY) process should be done first.
  • and then after goodFeaturesToTrack process, I've tried to indicate features in colored circle in frame.
  • So, I converted frame to 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?

1

There are 1 answers

7
rayryeng On BEST ANSWER

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