Вибір правильної верхньої та нижньої меж HSV для виявлення кольорів за допомогою `cv :: inRange` (OpenCV)


80

У мене є зображення кавової банки з помаранчевою кришкою, яку я хочу знайти. Ось воно зображення.

Утиліта gcolor2 показує ВПГ у центрі кришки (22, 59, 100). Питання в тому, як тоді вибрати межі кольору? Я спробував min = (18, 40, 90) та max = (27, 255, 255), але отримав несподіванерезультат

Ось код 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()

Я перевірив значення (22, 59, 100) як HSV, і, схоже, вони не відповідають жодному кольору, подібному до кольорів кришки. Але як BGR вони мають сенс. Як ви отримали ці значення?
karlphillip

Ось знімок екрана з gcolor2 imageshack.us/photo/my-images/23/rgb2hsv.png . Потім я перевірив номер кольору # FFA069 на yafla.com/yaflaColor/ColorRGBHSL.aspx?RGB=&Colors= ,,,,,,,,, і перетворення однакове.
Student FourK

4
Ймовірно, це пов’язано з різними діапазонами HSV у OpenCV, а саме H: 0 - 180, S: 0 - 255, V: 0 - 255.
Студент FourK

Відповіді:


146

Проблема 1: Різні програми використовують різні шкали для ВПГ. Наприклад, використання 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)

Тепер запустіть його. Я отримав результат наступним чином:

введіть тут опис зображення

Сподіваюся, це те, що ви хотіли. Є кілька помилкових виявлень, але вони невеликі, тому ви можете вибрати найбільший контур, який є вашою кришкою.

РЕДАГУВАТИ:

Як сказав Карл Філіп у своєму коментарі, було б добре додати новий код. Але відбувається зміна лише одного рядка. Отже, я хотів би додати той самий код, реалізований у новому 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)

Це дає той самий результат, що і вище. Але код набагато простіший.


+1 Відмінно, ще раз. Якби ви могли додати повний вихідний код зі своїми модифікаціями, це було б здорово.
karlphillip

Дякую. Але я не думаю, що тут є велика досконалість. :) (Добре, я це зроблю)
Абід Рахман К,

1
Чудово! Це працює і для мене зараз, хоча я вважаю, що ваші діапазони S і V min-max занадто розслаблені. У мене також гарне покриття кришкою з мінімальним (5, 100, 255) та максимальним (15, 200, 255).
Student FourK

Добре знати. Я взяв значення S, V просто для того, щоб показати результат, щоб показати, що це рішення працює. Добре, що ти знайшов кращих. Також спробуйте перейти на cv2інтерфейс. Це простіше і швидше. Ви можете знайти кілька хороших підручників тут: opencvpython.blogspot.com. І якщо це вирішить вашу проблему, прийміть відповідь і закрийте цю сесію.
Абід Рахман К,

У цьому місці кожен робить помилки, коли є новачками у OpenCv.
nbsrujan

58

Гаразд, знайти колір у HSVпросторі - це давнє, але поширене питання. Я зробив hsv-colormapдля швидкого пошуку спеціальний колір. Ось:

введіть тут опис зображення

Вісь 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) )

Потім ми використовуємо знайдений діапазон для пошуку помаранчевого кольору, це результат:

введіть тут опис зображення


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

#!/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


друга ланка поводиться дивно?
jtlz2

1
@ jtlz2: Вони просто відповіли на цю відповідь . Можливо, помилково.
Мартін Пітерс

Трохи пізно, але цікаво, як ви визначили значення V. У моїй заявці я використовую гістограми для визначення значень H / S, але не був впевнений у V. Що стосується 0-100% темності / освітленості, я думаю, у пристойно освітленій кімнаті ми б просто вибрали середнє значення?
Jacob David C. Cunningham

29

Я створив цю просту програму для отримання кодів 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's 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()

9
LOL, я написав той самий код із друком остаточних значень HSV, використовуючи github.com/saurabheights/ImageProcessingExperimentScripts/blob/…
saurabheights

17

Ось простий скрипт кольорового порогу HSV для визначення нижнього / верхнього діапазону кольорів за допомогою панелей треків для будь-якого зображення на диску. Просто змініть шлях до зображення вcv2.imread()

введіть тут опис зображення

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('1.jpg')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

while(1):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

Це було надзвичайно корисно. Зроблено виявити відповідний діапазон ВПГ в 20 разів швидше. Багато махало!
DCМожливо,

Оце Так! Надзвичайно корисний, як уже коментували. Дякую, що поділились!
KlopDesign

Чиста дивовижність! Щиро дякую
Семінко

4

Діапазон ВПЛ OpenCV становить: В: від 0 до 179 S: від 0 до 255 В: від 0 до 255

На Gimp (або іншій фотоманіпуляції sw) відтінок варіюється від 0 до 360, оскільки opencv розміщує інформацію про колір в одному байті, максимальне значення числа в одному байті становить 255, тому значення відтінку openCV еквівалентні значенням відтінку з gimp, поділеному на 2 .

Під час спроби виявлення об’єктів на основі кольорового простору HSV я виявив, що діапазону 5 (діапазон opencv) було достатньо для фільтрації певного кольору. Я порадив би вам використовувати кольорове піднебіння HSV, щоб визначити асортимент, який найкраще підходить для вашої програми.

HSV кольорове піднебіння з кольоровим виявленням у просторі HSV


3

Щоб знайти значення HSV зеленого, спробуйте виконати наступні команди в терміналі Python

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.