#ルービックキューブ色取得
Python 3.91
opencv 4.51
windows10
import cv2
import numpy as np
import sys
import time
import copy
import kociemba
import solve_arduino
class Camera:
def rubiks_solve(self):
count = 0
result_list = [[] for i in range(54) ]
#BGRで表示0-255
color_index =[[0,0,0],[0,0,0],[0,0,0],
[0,0,0],[0,0,0],[0,0,0],
[0,0,0],[0,0,0],[0,0,0]]
#色を UDRLBFで表示
color_key = ['black','black','black',
'black','black','black',
'black','black','black']
#取得する場所の指定
frame_yx = [[140, 350],[140, 590],[140, 830],
[370, 350],[300, 520],[370, 830],
[620, 350],[620, 590],[620, 830]]
#index4 default 320 540 420 640 370, 590
y_start = [90, 90, 90, 320, 270, 320, 570, 570, 570]
x_start = [300, 540, 780, 300, 490, 780, 300, 540, 780]
y_end = [190, 190, 190, 420, 470, 420, 670, 670, 670]
x_end = [400, 640, 880, 400, 690, 880, 400, 640, 880]
y_start2 = [30, 30, 30, 80, 80, 80, 130, 130, 130]
x_start2 = [30, 80, 130, 30, 80, 130, 30, 80, 130]
y_end2 = [70, 70, 70, 120, 120, 120, 170, 170, 170]
x_end2 = [70, 120, 170, 70, 120, 170, 70, 120, 170]
#GANCUVE BGR # U R F D L B
colors_BGR = {
'L': ([5, 20, 160], [75, 90, 189]), #red 6 4
'F': ([25, 130, 0], [100, 180, 30]), #green 3 2
'D': ([130, 130, 130], [255, 255, 255]), #white 2 3
'B': ([140, 80, 0], [255, 180, 50]), #blue 5 5
'R': ([5, 91, 190], [130, 150, 255]), #orange 4 1
'U': ([5, 150, 150], [110, 200, 200]) #yellow 1 0
}
KEY_COLOR = {
'L': (0, 0, 255),
'F': (0, 255, 0),
'D': (255, 255, 255),
'B': (255, 0, 0),
'R': (0, 128, 255),
'U': (0, 255, 255)
}
KEY_SLICE = {
'U': slice(0, 9),
'R': slice(9, 18),
'F': slice(18, 27),
'D': slice(27, 36),
'L': slice(36, 45),
'B': slice(45, 54)
}
# n は使わない
def solve_end():
for n_e in result:
if n_e in solve_arduino.arduino_code_end:
p_e = solve_arduino.arduino_code_end[n_e]
print(p_e, end='')
def solve_start():
for n_s in result:
if n_s in solve_arduino.arduino_code_start:
p_s = solve_arduino.arduino_code_start[n_s]
print(p_s, end='')
def solve_test():
w = 0
p = 1
while True:
try:
cube_code = result[w], result[p]
if cube_code in solve_arduino.arduino_code:
del result[w]
result[w] = solve_arduino.arduino_code[cube_code]
w += 1
p += 1
except IndexError:
break
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) # 横幅
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # 縦幅
while True:
ret, frame = cap.read()
if not ret:
break
#BGR取得場所の指定
for k, (xs, ys, xe, ye, xs2, ys2, xe2, ye2) in enumerate(zip
(x_start, y_start, x_end, y_end, x_start2, y_start2, x_end2, y_end2)):
cv2.rectangle(frame, (xs, ys), (xe, ye), (255, 255, 255), 2)
b1 = color_index[k][0]
g1 = color_index[k][1]
r1 = color_index[k][2]
if color_key[4] in KEY_COLOR:
b4, g4 ,r4 = KEY_COLOR[color_key[4]]
#左上に取得した色を表示
cv2.rectangle(frame, (xs2, ys2), (xe2, ye2), (int(b4), int(g4), int(r4)), -1)
cv2.rectangle(frame, (xs2, ys2), (xe2, ye2), (int(b1), int(g1), int(r1)), -1)
#BGRの取得位置
for i, (y,x) in enumerate(frame_yx):
pixel = frame[y, x]
b = pixel[0]
g = pixel[1]
r = pixel[2]
BGR = [b,g,r]
#指定した範囲(colors_BGR)のなかに 取得したBGRがあてはまるか
for color, ( lower, upper) in colors_BGR.items():
if lower[0] < BGR[0] and BGR[0] < upper[0]:
if lower[1] < BGR[1] and BGR[1] < upper[1]:
if lower[2] < BGR[2] and BGR[2] < upper[2]:
color_key[i] = color
color_index[i] = BGR
if color_key[i] != 'black':
#print(color_key)
#print(color_index)
pass
#TAB 取得した色をリストに追加
key3 = cv2.waitKey(1)
if key3 == 9:
if color_key[4] in KEY_SLICE:
result_list[KEY_SLICE[color_key[4]]] = color_key
print(result_list)
time.sleep(0.5)
# @ arduino 用のプログラムをプリント
key4 = cv2.waitKey(1)
if key4 == 64:
result = ''.join(result_list)
try:
print("OK")
result = kociemba.solve(result)
result = result.replace(' ', ',')
result = result.split(',')
print(result)
print("solve_end")
solve_test()
print(result)
solve_end()
print(len(result))
result.reverse()
print()
print("solve_start")
solve_test()
solve_start()
count = 0
except ValueError:
print("ValueError")
count += 1
result_list = [[] for i in range(54) ]
time.sleep(2)
if count == 3:
break
#print("resilt= ", result)
cv2.imshow("Frame", frame)
#esc
key2 = cv2.waitKey(1)
if key2 == 27:
break
cap.release()
cv2.destroyAllWindows()
cam = Camera()
cam.rubiks_solve()
#arduino用に変換する(回転記号) ```solve_arduino.py arduino_code_start= { "R": '\"R\'\",', "R\'": "\'R\',", "R2": '\"R2\",', "U": '\"U\'\",', "U\'": "\'U\',", "U2": '\"U2\",', "D": '\"D\'\",', "D\'": "\'D\',", "D2": '\"D2\",', "L": '\"L\'\",', "L\'": "\'L\',", "L2": '\"L2\",', "F": '\"F\'\",', "F\'": "\'F\',", "F2": '\"F2\",', "B": '\"B\'\",', "B\'": "\'B\',", "B2": '\"B2\",', "RL": '\"R\'L\'\",', "RL\'": '\"R\'L\",', "RL2": '\"R\'L2\",', "R'L": '\"RL\'\",', "R'L'": '\"RL\",', "R'L2": '\"RL2\",', "R2L": '\"R2L\'\",', "R2L\'": '\"R2L\",', "R2L2": '\"R2L2\",', "FB": '\"F\'B\'\",', "FB\'": '\"F\'B\",', "FB2": '\"F\'B2\",', "F\'B": '\"FB\'\",', "F\'B\'": '\"FB\",', "F\'B2": '\"FB2\",', "F2B": '\"F2B\'\",', "F2B\'": '\"F2B\",', "F2B2": '\"F2B2\",', "UD": '\"U\'D\'\",', "UD\'": '\"U\'D\",', "UD2": '\"U\'D2\",', "U\'D": '\"UD\'\",', "U\'D\'": '\"UD\",', "U\'D2": '\"UD2\",', "U2D": '\"U2D\'\",', "U2D\'": '\"U2D\",', "U2D2": '\"U2D2\",' }
arduino_code_end = {
"R": "'R',",
"R'": '"R'",',
"R2": '"R2",',
"U": "'U',",
"U'": '"U'",',
"U2": '"U2",',
"D": "'D',",
"D'": '"D'",',
"D2": '"D2",',
"L": "'L',",
"L'": '"L'",',
"L2": '"L2",',
"F": "'F',",
"F'": '"F'",',
"F2": '"F2",',
"B": "'B',",
"B'": '"B'",',
"B2": '"B2",',
"RL": '"RL",',
"RL'": '"RL'",',
"RL2": '"RL2",',
"R'L": '"R'L",',
"R'L'": '"R'L'",',
"R'L2": '"R'L2",',
"R2L": '"R2L",',
"R2L'": '"R2L'",',
"R2L2": '"R2L2",',
"FB": '"FB",',
"FB'": '"FB'",',
"FB2": '"FB2",',
"F'B": '"F'B",',
"F'B'": '"F'B'",',
"F'B2": '"F'B2",',
"F2B": '"F2B",',
"F2B'": '"F2B'",',
"F2B2": '"F2B2",',
"UD": '"UD",',
"UD'": '"UD'",',
"UD2": '"UD2",',
"U'D": '"U'D",',
"U'D'": '"U'D'",',
"U'D2": '"U'D2",',
"U2D": '"U2D",',
"U2D'": '"U2D'",',
"U2D2": '"U2D2",'
}
arduino_code ={
("R", "L") :("RL"),
("L", "R") :("RL"),
("R'", "L") :("RL'"),
("R", "L'") :("RL'"),
("L'", "R") :("RL'"),
("L", "R'") :("RL'"),
("R", "L2") :("RL2"),
("R2", "L") :("RL2"),
("L", "R2"): ("RL2"),
("L2", "R"): ("RL2"),
("R2", "L'") :("R'L2"),
("R'", "L2") :("R'L2"),
("L2", "R'") :("R'L2"),
("L'", "R2") :("R'L2"),
("R2", "L2") :("R2L2"),
("L2", "R2") :("R2L2"),
("F", "B") :("FB"),
("B", "F") :("FB"),
("F'", "B") :("FB'"),
("F","B'") :("FB'"),
("B'", "F") :("FB'"),
("B", "F'") :("FB'"),
("F", "B2") :("FB2"),
("F2", "B") :("FB2"),
("B", "F2"): ("FB2"),
("B2", "F"): ("FB2"),
("F2", "B'") :("F'B2"),
("F'", "B2") :("F'B2"),
("B2", "F'") :("F'B2"),
("B'", "F2") :("F'B2"),
("F2", "B2") :("F2B2"),
("B2", "F2") :("F2B2"),
("U", "D") :("UD"),
("D", "U") :("UD"),
("U'", "D") :("UD'"),
("U", "D'") :("UD'"),
("D'", "U") :("UD'"),
("D", "U'") :("UD'"),
("U", "D2") :("UD2"),
("U2", "D") :("UD2"),
("D", "U2"): ("UD2"),
("D2", "U"): ("UD2"),
("U2", "D'") :("U'D2"),
("U'", "D2") :("U'D2"),
("D2", "U'") :("U'D2"),
("D'", "U2") :("U'D2"),
("U2", "D2") :("U2D2"),
("D2", "U2") :("U2D2"),
}