Python OpenCV:魔方解算器颜色提取

Python OpenCV: Rubik#39;s cube solver color extraction(Python OpenCV:魔方解算器颜色提取)
本文介绍了Python OpenCV:魔方解算器颜色提取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

说明:

我正在使用 Python & 解决魔方问题.开放式简历.为此,我试图提取立方体的所有颜色(单个立方体块),然后应用适当的算法(我设计的,没有问题).

问题:

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

我做了什么:

这里我刚刚提取了黄色.

颜色提取后:

原图

守则

将 numpy 导入为 np导入简历2从 cv2 导入 *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图像COLOR_MIN = np.array([20, 100, 100],np.uint8) # HSV 颜色代码上下界COLOR_MAX = np.array([30, 255, 255],np.uint8) # 黄色frame_threshed = cv2.inRange(hsv_img, COLOR_MIN, COLOR_MAX) # 阈值图像imgray = frame_threshedret,thresh = cv2.threshold(frame_threshed,127,255,0)轮廓,层次结构 = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)打印类型(轮廓)对于轮廓中的cnt:x,y,w,h = cv2.boundingRect(cnt)打印 x,打印 ycv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)cv2.imshow("显示",im)cv2.imwrite("提取的.jpg", im)cv2.waitKey()cv2.destroyAllWindows()

请就如何定位小方块的位置提出一些建议.这里发现了 4 个黄色立方体:右上角、中心、右边缘、左下角.我如何识别这些位置,例如:通过为每个位置分配数字(这里:3、4、5、7)

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

P.S.:OpenCV 新手 :)

解决方案

这里有一个简单的方法:

  • 将图片转换为 HSV 格式
  • 使用颜色阈值检测具有 从上到下或从下到上对轮廓进行排序.接下来,我们取每行 3 个正方形,并从左到右或从右到左对这一行进行排序.这是排序的可视化(从上到下,左)或(从下到上,右)

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

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

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

    导入 cv2将 numpy 导入为 np从 imutils 导入轮廓图像 = cv2.imread('1.png')原始 = image.copy()图像 = cv2.cvtColor(图像,cv2.COLOR_BGR2HSV)掩码 = np.zeros(image.shape,dtype=np.uint8)颜色 = {'灰色': ([76, 0, 41], [179, 255, 70]), # 灰色'蓝色': ([69, 120, 100], [179, 255, 255]), # 蓝色'黄色': ([21, 110, 117], [45, 255, 255]), # 黄色'橙色': ([0, 110, 125], [17, 255, 255]) # 橙色}# 找到正方形的颜色阈值open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))对于颜色,(lower,upper) 在 colors.items() 中:较低 = np.array(较低,dtype=np.uint8)上= np.array(上,dtype=np.uint8)color_mask = cv2.inRange(图像,下,上)color_mask = cv2.morphologyEx(color_mask, cv2.MORPH_OPEN, open_kernel, 迭代次数=1)color_mask = cv2.morphologyEx(color_mask, cv2.MORPH_CLOSE, close_kernel, 迭代次数=5)color_mask = cv2.merge([color_mask, color_mask, color_mask])mask = cv2.bitwise_or(mask, color_mask)灰色 = cv2.cvtColor(掩码,cv2.COLOR_BGR2GRAY)cnts = cv2.findContours(灰色,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = cnts[0] 如果 len(cnts) == 2 否则 cnts[1]# 从上到下或从下到上对所有轮廓进行排序(cnts, _) = contours.sort_contours(cnts, method=从上到下")# 取每行 3 并从左到右或从右到左排序立方体行 = []行 = []对于枚举(cnts,1)中的(i,c):row.append(c)如果我 % 3 == 0:(cnts, _) = contours.sort_contours(row, method=从左到右")cube_rows.append(cnts)行 = []# 绘制文字数字 = 0对于 cube_rows 中的行:对于 c 行:x,y,w,h = cv2.boundingRect(c)cv2.rectangle(原始, (x, y), (x + w, y + h), (36,255,12), 2)cv2.putText(原始,#{}".format(数字 + 1),(x,y - 5),cv2.FONT_HERSHEY_SIMPLEX,0.7,(255,255,255),2)数字 += 1cv2.imshow('掩码', 掩码)cv2.imwrite('mask.png', 掩码)cv2.imshow('原创', 原创)cv2.waitKey()

    Description:

    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).

    The problem:

    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?

    What I've done:

    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()
    

    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 newbie :)

    解决方案

    Here's a simple approach:

    • 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

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

    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:魔方解算器颜色提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

    本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Reading *.mhd/*.raw format in python(在 python 中读取 *.mhd/*.raw 格式)
Count number of cells in the image(计算图像中的单元格数)
How to detect paragraphs in a text document image for a non-consistent text structure in Python OpenCV(如何在 Python OpenCV 中检测文本文档图像中的段落是否存在不一致的文本结构)
How to get the coordinates of the bounding box in YOLO object detection?(YOLO物体检测中如何获取边界框的坐标?)
Divide an image into 5x5 blocks in python and compute histogram for each block(在 python 中将图像划分为 5x5 块并计算每个块的直方图)
Extract cow number from image(从图像中提取奶牛编号)