Подтвердить что ты не робот

Выбор правильных верхних и нижних границ HSV для определения цвета с помощью 'cv :: inRange' (OpenCV)

У меня есть изображение кофе с оранжевой крышкой, которую я хочу найти. Вот он image.

Утилита

gcolor2 показывает HSV в центре крышки (22, 59, 100). Вопрос в том, как выбрать границы цвета? Я попробовал min = (18, 40, 90) и max = (27, 255, 255), но получил неожиданный result

Вот код Python:

import cv

in_image = 'kaffee.png'
out_image = 'kaffee_out.png'
out_image_thr = 'kaffee_thr.png'

ORANGE_MIN = cv.Scalar(18, 40, 90)
ORANGE_MAX = cv.Scalar(27, 255, 255)
COLOR_MIN = ORANGE_MIN
COLOR_MAX = ORANGE_MAX

def test1():
    frame = cv.LoadImage(in_image)
    frameHSV = cv.CreateImage(cv.GetSize(frame), 8, 3)
    cv.CvtColor(frame, frameHSV, cv.CV_RGB2HSV)
    frame_threshed = cv.CreateImage(cv.GetSize(frameHSV), 8, 1)
    cv.InRangeS(frameHSV, COLOR_MIN, COLOR_MAX, frame_threshed)
    cv.SaveImage(out_image_thr, frame_threshed)

if __name__ == '__main__':
    test1()
4b9b3361

Ответ 1

Проблема 1: Различные приложения используют разные шкалы для HSV. Например, gimp использует H = 0-360, S = 0-100 and V = 0-100. Но OpenCV использует H: 0-179, S: 0-255, V: 0-255. Здесь я получил значение оттенка 22 в GIMP. Поэтому я взял половину, 11, и определил диапазон для этого. т.е. (5,50,50) - (15,255,255).

Проблема 2: А также, OpenCV использует формат BGR, а не RGB. Поэтому измените код, который преобразует RGB в HSV, следующим образом:

cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV)

Теперь запустите это. Я получил вывод следующим образом:

enter image description here

Надеюсь, это то, что вы хотели. Есть несколько ложных обнаружений, но они маленькие, поэтому вы можете выбрать самый большой контур, которым является ваша крышка.

РЕДАКТИРОВАТЬ:

Как сказал в своем комментарии Карл Филипп, было бы неплохо добавить новый код. Но есть изменение только одной строки. Итак, я хотел бы добавить тот же код, реализованный в новом модуле cv2, чтобы пользователи могли сравнить легкость и гибкость нового модуля cv2.

import cv2
import numpy as np

img = cv2.imread('sof.jpg')

ORANGE_MIN = np.array([5, 50, 50],np.uint8)
ORANGE_MAX = np.array([15, 255, 255],np.uint8)

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

frame_threshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX)
cv2.imwrite('output2.jpg', frame_threshed)

Это дает тот же результат, что и выше. Но код намного проще.

Ответ 2

Я создал эту простую программу для получения кодов HSV в реальном времени

import cv2
import numpy as np


cap = cv2.VideoCapture(0)

def nothing(x):
    pass
# Creating a window for later use
cv2.namedWindow('result')

# Starting with 100 to prevent error while masking
h,s,v = 100,100,100

# Creating track bar
cv2.createTrackbar('h', 'result',0,179,nothing)
cv2.createTrackbar('s', 'result',0,255,nothing)
cv2.createTrackbar('v', 'result',0,255,nothing)

while(1):

    _, frame = cap.read()

    #converting to HSV
    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)

    # get info from track bar and appy to result
    h = cv2.getTrackbarPos('h','result')
    s = cv2.getTrackbarPos('s','result')
    v = cv2.getTrackbarPos('v','result')

    # Normal masking algorithm
    lower_blue = np.array([h,s,v])
    upper_blue = np.array([180,255,255])

    mask = cv2.inRange(hsv,lower_blue, upper_blue)

    result = cv2.bitwise_and(frame,frame,mask = mask)

    cv2.imshow('result',result)

    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cap.release()

cv2.destroyAllWindows()

Ответ 3

Хорошо, найти цвет в пространстве HSV - это старый, но общий вопрос. Я сделал hsv-colormap чтобы быстро найти особый цвет. Вот:

enter image description here

Ось X представляет Hue в [0,180), ось y1 представляет Saturation в [0,255], ось y2 представляет S = 255, а V = 255.

Чтобы найти цвет, обычно просто найдите диапазон H и S и установите v в диапазоне (20, 255).

Чтобы найти оранжевый цвет, мы ищем карту и находим лучший диапазон: H :[10, 25], S: [100, 255], and V: [20, 255]. Таким образом, маска является cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )

Затем мы используем найденный диапазон для поиска оранжевого цвета, это результат:

enter image description here


Метод прост, но распространен для использования:

#!/usr/bin/python3
# 2018.01.21 20:46:41 CST
import cv2

img = cv2.imread("test.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )
cv2.imshow("orange", mask);cv2.waitKey();cv2.destroyAllWindows()

Похожие ответы:

  1. Как определить пороговое значение для обнаружения только объектов зеленого цвета в изображении: Opencv

  2. Выбор правильных значений HSV для порога OpenCV с помощью InRangeS

Ответ 4

Диапазон OpenVV HSV: H: от 0 до 179 S: от 0 до 255 V: от 0 до 255

В Gimp (или другой манипуляции с фотографиями sw) диапазон оттенков от 0 до 360, так как opencv помещает информацию о цвете в один байт, максимальное числовое значение в одном байте равно 255, поэтому значения openCV Hue эквивалентны значениям оттенка от gimp разделен на 2.

Я обнаружил, что при попытке обнаружения объекта на основе цветового пространства HSV диапазон 5 (диапазон opencv) был достаточным для фильтрации определенного цвета. Я бы посоветовал вам использовать цветное неба HSV, чтобы выяснить диапазон, который лучше всего подходит для вашего приложения.

Цветовое небо HSV с обнаружением цвета в пространстве HSV

Ответ 5

Чтобы найти значение HSV для Green, попробуйте следующие команды в терминале Python

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]