Проверка, попадают ли определенные пиксели в цветовые диапазоны?

Я использую OpenCV в Python для создания программы, которая решает кубик Рубика. Я не создаю свой собственный алгоритм решения, но я использую реализацию kociemba на python.

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

Я пытался:

        _, img = self.cap.read()
        print('frame captured!')

        hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
        #scan each pixel in the list
        for a in self.pixelsToScan:
            hue = hsv[a[1],a[0],0]
            print(hue)
            sat = hsv[a[1],a[0],1]/255
            print(sat)
            val = hsv[a[1],a[0],2]/255
            print(val)

            #CHANGE COLOR CHECKING TO USE inRange()#

            if sat<.15 and val>.85:
                #WHITE
                self.colors = self.colors + 'U'
            elif hue<7 or hue>=173:
                #RED
                self.colors = self.colors + 'F'
            elif hue>=7 and hue<22:
                #ORANGE
                self.colors = self.colors + 'B'
            elif hue>=22 and hue<37:
                #YELLOW
                self.colors = self.colors + 'D'
            elif hue>=37 and hue<67:
                #GREEN
                self.colors = self.colors + 'L'
            elif hue>=67 and hue<135:
                #BLUE
                self.colors = self.colors + 'R'
            else:
                #BROKEN
                self.colors = self.colors + 'E'

Так же как:

        _, img = self.cap.read()
        print('frame captured!')

        #scan each pixel in the list
        for a in self.pixelsToScan:

            if cv.inRange(numpy.copy(img), self.WHITE_MIN, self.WHITE_MAX)[a[1],a[0]]==255:
                #WHITE
                self.colors = self.colors + 'U'
            elif cv.inRange(numpy.copy(img), self.RED_LOWER_MIN, self.RED_LOWER_MAX)[a[1],a[0]]==255 or cv.inRange(numpy.copy(img), self.RED_UPPER_MIN, self.RED_UPPER_MAX)[a[1],a[0]]==255:
                #RED
                self.colors = self.colors + 'F'
            elif cv.inRange(numpy.copy(img), self.ORANGE_MIN, self.ORANGE_MAX)[a[1],a[0]]==255:
                #ORANGE
                self.colors = self.colors + 'B'
            elif cv.inRange(numpy.copy(img), self.YELLOW_MIN, self.YELLOW_MAX)[a[1],a[0]]==255:
                #YELLOW
                self.colors = self.colors + 'D'
            elif cv.inRange(numpy.copy(img), self.GREEN_MIN, self.GREEN_MAX)[a[1],a[0]]==255:
                #GREEN
                self.colors = self.colors + 'L'
            elif cv.inRange(numpy.copy(img), self.BLUE_MIN, self.BLUE_MAX)[a[1],a[0]]==255:
                #BLUE
                self.colors = self.colors + 'R'
            else:
                #BROKEN
                self.colors = self.colors + 'E'

Я понятия не имею, как я мог бы надежно проверить, какой цвет у каждого изделия, так как освещение постоянно меняется. Я думал, используя inRange() функции были бы то, что мне нужно, но это просто не работает по какой-то причине. И каждый диапазон различен, поэтому я не знаю ни одного способа проверить один и тот же пиксель на одном и том же изображении по всем из них.

Серьезно, любая помощь будет принята с благодарностью. Заранее спасибо!

РЕДАКТИРОВАТЬ: Я сейчас также попробовал следующее:

        _, img = self.cap.read()
        print('frame captured!')

        hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
        #scan each pixel in the list
        for a in self.pixelsToScan:
            r = img[a[1],a[0],2]
            g = img[a[1],a[0],1]
            b = img[a[1],a[0],0]

            if r>220 and g>220 and b>220:
                #WHITE
                self.colors = self.colors + 'U'
            elif r>=175 and g<=60 and b<=60:
                #RED
                self.colors = self.colors + 'F'
            elif r>=175 and g>=96 and g<=171 and b<=54:
                #ORANGE
                self.colors = self.colors + 'B'
            elif r>=205 and r <= 213 and g>=175 and b<=41:
                #YELLOW
                self.colors = self.colors + 'D'
            elif r<=96 and g>=175 and b<=128:
                #GREEN
                self.colors = self.colors + 'L'
            elif r>=54 and r<=85 and g<=116 and b >=179:
                #BLUE
                self.colors = self.colors + 'R'
            else:
                #BROKEN
                self.colors = self.colors + 'E'

Пределы rgb были созданы с использованием моих границ hsv из ранее.

Вот изображение с желаемым выводом:

У меня есть это изображение одного лица кубика Рубика:Кубик Рубика

Это должно произвести вывод LDLLFLBRR но это либо даст результат EEEEEEEEE, представляющий все ошибки, или `LULLFRFRR ', означающий, что оранжевый определяется как красный, желтый как белый, а зеленый иногда как синий.

Что мне нужно, так это надежный способ всегда знать, какой цвет какой.

Спасибо за любую помощь!

1 ответ

Я подозреваю, что вы смотрите на один пиксель, чтобы определить цвет стикера, и в области стикера есть много вариантов.

Кажется, что каждая наклейка имеет размер около 510x510 пикселей, поэтому я бы посоветовал вам попробовать сделать коробку в среднем размером не менее 100x100 пикселей до цветового тестирования.

Другие вопросы по тегам