Как преобразовать изображение в оттенках серого в RGB в OpenCV (Python) для визуализации контуров после обработки изображения в двоичном формате?
Я изучаю обработку изображений, используя OpenCV для приложения реального времени. Я сделал некоторые пороговые значения на изображении и хочу наметить контуры зеленым цветом, но они не отображаются зеленым цветом, потому что мое изображение черно-белое.
В начале программы я использовал grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) для преобразования из RGB в оттенки серого, но чтобы вернуться назад, я запутался, а функция backtorgb = cv2.cvtColor(gray, cv2.CV_GRAY2RGB ) дает AttributeError: объект 'module' не имеет атрибута 'CV_GRAY2RGB'.
В приведенном ниже коде не отображаются контуры рисунка зеленым цветом - это потому, что это изображение в оттенках серого? Если это так, можно ли преобразовать изображение в оттенках серого в RGB, чтобы визуализировать контуры зеленым?
import numpy as np
import cv2
import time
cap = cv2.VideoCapture(0)
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
ret, gb = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)
gb = cv2.bitwise_not(gb)
contour,hier = cv2.findContours(gb,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contour:
cv2.drawContours(gb,[cnt],0,255,-1)
gray = cv2.bitwise_not(gb)
cv2.drawContours(gray,contour,-1,(0,255,0),3)
cv2.imshow('test', gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Ответы
Ответ 1
Я продвигаю свой комментарий к ответу:
Простым способом является:
Вы можете нарисовать исходный "фрейм" вместо использования серого изображения.
Трудный способ (метод, который вы пытались реализовать):
backtorgb = cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB)
- правильный синтаксис.
Ответ 2
Попробуйте следующее:
import cv2
import cv
color_img = cv2.cvtColor(gray_img, cv.CV_GRAY2RGB)
При использовании opencv я обнаружил, что некоторые константы определены в модуле cv2 и другие в cv-модуле.
Ответ 3
Вы конвертируете свое изображение в серый цвет, вы не можете вернуться. Вы перешли с трех каналов на один, когда вы попытаетесь вернуться назад, все три номера будут одинаковыми. Итак, короткий ответ - нет, вы не можете вернуться. Причина, по которой ваша функция backtorgb выполняет эту ошибку, заключается в том, что она должна быть в формате:
CvtColor(input, output, CV_GRAY2BGR)
OpenCV использует BGR, а не RGB, поэтому, если вы исправляете заказ, он должен работать, хотя ваше изображение будет по-прежнему серым.
Ответ 4
В качестве альтернативы, cv2.merge()
можно использовать для преобразования одноканального двоичного маскирующего слоя в трехканальное цветное изображение путем объединения одного и того же слоя с синим, зеленым и красным слоями нового изображения. Мы передаем список из трех слоев цветовых каналов - в данном случае все одинаковые - и функция возвращает одно изображение с этими цветными каналами. Это эффективно преобразует серое изображение формы (height, width, 1)
в (height, width, 3)
Для решения вашей проблемы
Я сделал несколько пороговых значений для изображения и хочу обозначить контуры зеленым, но они не отображаются зеленым, потому что мое изображение черно-белое.
Это потому, что вы пытаетесь отобразить три канала на изображении одного канала. Чтобы это исправить, вы можете просто объединить три отдельных канала
image = cv2.imread('image.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_three = cv2.merge([gray,gray,gray])
Пример
Мы создаем цветное изображение с размерами (200,200,3)
![enter image description here]()
image = (np.random.standard_normal([200,200,3]) * 255).astype(np.uint8)
Затем мы конвертируем его в оттенки серого и создаем другое изображение, используя cv2.merge()
с тремя серыми каналами
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_three = cv2.merge([gray,gray,gray])
Теперь мы рисуем закрашенный контур на одноканальном изображении в градациях серого (слева) с формой (200,200,1)
и на трехканальном изображении в градациях серого с формой (200,200,3)
(справа). На левом изображении показана проблема, с которой вы столкнулись, поскольку вы пытаетесь отобразить три канала на изображении с одним каналом. После объединения изображения в градациях серого в три канала, теперь мы можем применить цвет к изображению
![enter image description here]()
contour = np.array([[10,10], [190, 10], [190, 80], [10, 80]])
cv2.fillPoly(gray, [contour], [36,255,12])
cv2.fillPoly(gray_three, [contour], [36,255,12])
Полный код
import cv2
import numpy as np
# Create random color image
image = (np.random.standard_normal([200,200,3]) * 255).astype(np.uint8)
# Convert to grayscale (1 channel)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Merge channels to create color image (3 channels)
gray_three = cv2.merge([gray,gray,gray])
# Fill a contour on both the single channel and three channel image
contour = np.array([[10,10], [190, 10], [190, 80], [10, 80]])
cv2.fillPoly(gray, [contour], [36,255,12])
cv2.fillPoly(gray_three, [contour], [36,255,12])
cv2.imshow('image', image)
cv2.imshow('gray', gray)
cv2.imshow('gray_three', gray_three)
cv2.waitKey()