Проверка, попадают ли определенные пиксели в цветовые диапазоны? - PullRequest
0 голосов
/ 13 июня 2018

Я использую 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 ранее.

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

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

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

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

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

1 Ответ

0 голосов
/ 13 июня 2018

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

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

...