Python OpenCV:Rubik的多维数据集求解器颜色提取 [英] Python OpenCV: Rubik's cube solver color extraction

查看:82
本文介绍了Python OpenCV:Rubik的多维数据集求解器颜色提取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明:

我正在使用Python&来解决rubiks多维数据集. OpenCV.为此,我尝试提取立方体(单个立方体)的所有颜色,然后应用适当的算法(我已经设计了该算法,那里没有问题).

I am working on solving rubiks cube using Python & OpenCV. For this purpose I am trying to extract all the colors of the cubies(individual cube pieces) and then applying appropriate algorithm(which I've designed, no issues there).

问题:

假设我已经提取了cubices的所有颜色,那么如何定位提取cubices的位置?我怎么知道它是在上中下层还是在角落中边缘?

Suppose if I've extracted all the colors of the cubies, how I can locate the position of the extracted cubies? How will I know whether it is in top-middle-lower layer or whether its a corner-middle-edge piece?

我所做的事情:

这里我刚刚提取了黄色.

Here I have just extracted yellow color.

颜色提取后:

After color extraction:

原始图片

Original Image

代码

The Code

import numpy as np
import cv2
from cv2 import *

im = cv2.imread('v123.bmp')
im = cv2.bilateralFilter(im,9,75,75)
im = cv2.fastNlMeansDenoisingColored(im,None,10,10,7,21)
hsv_img = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)   # HSV image


COLOR_MIN = np.array([20, 100, 100],np.uint8)       # HSV color code lower and upper bounds
COLOR_MAX = np.array([30, 255, 255],np.uint8)       # color yellow 

frame_threshed = cv2.inRange(hsv_img, COLOR_MIN, COLOR_MAX)     # Thresholding image
imgray = frame_threshed
ret,thresh = cv2.threshold(frame_threshed,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print type(contours)
for cnt in contours:
    x,y,w,h = cv2.boundingRect(cnt)
    print x,
    print y
    cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("Show",im)
cv2.imwrite("extracted.jpg", im)
cv2.waitKey()
cv2.destroyAllWindows()

请提供一些有关如何确定小柜位置的建议.在这里发现了4个黄色小球:右上角,中间,右边缘,左下角.如何识别这些位置,例如:通过为每个位置分配数字(此处为3、4、5、7)

Please give some suggestions on how can I locate the positions of the cubies. Here 4 yellow cubies are spotted: top-right-corner, center, right-edge, bottom-left-corner. How can I identify these positions for eg: by assigning digits to each position (here: 3, 4, 5, 7)

感谢任何帮助/想法:)谢谢.

Any help/idea is appreciated :) Thanks.

P.S.:OpenCV新手:)

P.S.: OpenCV newbie :)

推荐答案

这是一种简单的方法:

  • Convert image to HSV format
  • Use color thresholding to detect the squares with cv2.inRange
  • Perform morphological operations and draw squares onto a mask
  • Find contours on mask and sort from top-bottom or bottom-top
  • Take each row of three squares and sort from left-right or right-left

转换为HSV格式后,我们使用cv2.inRange()执行颜色阈值检测正方形.我们将检测到的正方形绘制到蒙版上

After converting to HSV format, we perform color thresholding using cv2.inRange() to detect the squares. We draw the detected squares onto a mask

从这里我们在蒙版上找到轮廓,并利用 imutils.contours.sort_contours() 进行排序从顶部到底部或从底部到顶部的轮廓.接下来,我们每行3个正方形,并按从左到右或从右到左的顺序对这一行进行排序.这是排序方式的可视化(左上角)或(右下角)

From here we find contours on the mask and utilize imutils.contours.sort_contours() to sort the contours from top-to-bottom or bottom-to-top. Next we take each row of 3 squares and sort this row from left-to-right or right-to-left. Here's a visualization of the sorting (top-bottom, left) or (bottom-top, right)

现在我们已经对轮廓进行了排序,我们只需将矩形绘制到图像上即可.这是结果

Now that we have the contours sorted, we simply draw the rectangles onto our image. Here's the results

从左至右和自上而下(左),从右至左和自上而下

Left-to-right and top-to-bottom (left), right-to-left and top-to-bottom

从左到右和从下到上(左),从右到左和从下到上

Left-to-right and bottom-to-top (left), right-to-left and bottom-to-top

import cv2
import numpy as np
from imutils import contours

image = cv2.imread('1.png')
original = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = np.zeros(image.shape, dtype=np.uint8)

colors = {
    'gray': ([76, 0, 41], [179, 255, 70]),        # Gray
    'blue': ([69, 120, 100], [179, 255, 255]),    # Blue
    'yellow': ([21, 110, 117], [45, 255, 255]),   # Yellow
    'orange': ([0, 110, 125], [17, 255, 255])     # Orange
    }

# Color threshold to find the squares
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
for color, (lower, upper) in colors.items():
    lower = np.array(lower, dtype=np.uint8)
    upper = np.array(upper, dtype=np.uint8)
    color_mask = cv2.inRange(image, lower, upper)
    color_mask = cv2.morphologyEx(color_mask, cv2.MORPH_OPEN, open_kernel, iterations=1)
    color_mask = cv2.morphologyEx(color_mask, cv2.MORPH_CLOSE, close_kernel, iterations=5)

    color_mask = cv2.merge([color_mask, color_mask, color_mask])
    mask = cv2.bitwise_or(mask, color_mask)

gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# Sort all contours from top-to-bottom or bottom-to-top
(cnts, _) = contours.sort_contours(cnts, method="top-to-bottom")

# Take each row of 3 and sort from left-to-right or right-to-left
cube_rows = []
row = []
for (i, c) in enumerate(cnts, 1):
    row.append(c)
    if i % 3 == 0:  
        (cnts, _) = contours.sort_contours(row, method="left-to-right")
        cube_rows.append(cnts)
        row = []

# Draw text
number = 0
for row in cube_rows:
    for c in row:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(original, (x, y), (x + w, y + h), (36,255,12), 2)

        cv2.putText(original, "#{}".format(number + 1), (x,y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)
        number += 1

cv2.imshow('mask', mask)
cv2.imwrite('mask.png', mask)
cv2.imshow('original', original)
cv2.waitKey()

这篇关于Python OpenCV:Rubik的多维数据集求解器颜色提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆