Кадры не видны в масштабе BGR (OpenCV)

#python #opencv #slam

#питон #opencv #хлоп

Вопрос:

Я пытаюсь написать код для SLAM с использованием OpenCV с нуля. Пока я пытаюсь показать обнаруженные объекты из каждого кадра в виде цветной круглой метки, у меня возникла проблема с отображением этого в цвете.

Краткие сведения

  • Для goodFeaturesToTrack функции cv2.cvtColor(img, cv2.BGR2GRAY) сначала должен быть выполнен процесс.
  • а затем, после goodFeaturesToTrack обработки, я попытался указать объекты в цветном круге в кадре.
  • Итак, я преобразовал фрейм в cv2.GRAY2BGR

Я ожидал увидеть цветные круглые метки в рамке, но в настоящее время их не видно.

 #! /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) amp; 0xFF == ord('q'):
                break
        else:
            break

    cap.release()
    cv.destroyAllWindows()
 

Но ошибка появляется, как показано ниже, после того, как я запускаю этот код.

 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::_InputArrayamp;; cv::OutputArray = const cv::_OutputArrayamp;]'
> Invalid number of channels in input image:
>     'VScn::contains(scn)'
> where
>     'scn' is 3
 

Как я могу это исправить?

Ответ №1:

Ваше изображение имеет оттенки серого, и поэтому, когда вы пытаетесь нарисовать цветные круги на изображении, вы не можете, поскольку существует только один канал, в отличие от ожидаемых трех для цветных изображений. Что вам нужно сделать, так это создать отдельную копию фрейма, чтобы вы могли запустить обнаружение интересующей точки на нем, получить углы и нарисовать их на цветной версии изображения вместо этого.

 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
 

Наконец, в вашем while цикле, поскольку изображение теперь цветное, вы можете удалить инструкцию преобразования из оттенков серого в цвет, поскольку функция возвращает изображение уже в цвете.

    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) amp; 0xFF == ord('q'):
                break
        else:
            break
 

Комментарии:

1. Спасибо за ответ. но я уже пробовал это раньше … ошибка появляется после этого утверждения. » Недопустимое количество каналов во входном изображении:> ‘VScn::contains(scn)’> где> ‘scn’ равно 3 »

2. @HenryKIM Это потому, что вам нужно удалить этот оператор в цикле while. Изображение уже цветное, как только вы его преобразовали. Я отредактирую свой ответ.

3. наконец ошибка устранена. Но мне интересно, почему фрейм все еще находится в серой шкале с цветной меткой. Я хочу видеть цветную метку в масштабируемой рамке RGB.

4. Вам нужно сделать копию входного цветного изображения. Вы не сказали мне, что это было вашим намерением. Я отредактирую… Еще раз.

5. Да, я сделал это, спасибо за руководство новым стековым цветком 🙂