ルービックキューブの回転記号をえる
複数の記事になります。
ルービックキューブの色を取得して kociembaを利用して
最後は回転記号を取得します。
NO.1 カメラ起動+BGR取得
NO.2 ウィンドウに取得した色を表示
NO.3取得したいろが 何色なのか 区別する
[NO.5 最終コード 参考程度に,,,,]
(https://qiita.com/otoboke162/private/c8b5417cb8a8c5af12f8)
kociembaを使います [参考、こちらはkociiemba](https://github.com/muodov/kociemba)
ルービックキューブの色を取得して kociembaを使えば 回転記号を得られます
kociembaをわかりやすくしてくれてます
kociembaの使い方として
こちらでも 説明されてる 通り ルービックキューブを 展開してかんがえる必要があります。
ルービックキューブを展開するとこんなかんじ
(日本配色と世界配色でルービックキューブの色の配置が違うので注意してください *これは世界配色)
緑が正面だとすると
緑:F(front) 赤:L(left) 橙:R(right)
黄:U(up) 白:D(down) 青:B(back)
になります まづは 色を 記号(F,L,R,U,D,B)にしたあと
数字のように並べ替える必要があります
U0~8 R9~17 F18~26 D27~35 L36~44 B45~53
ルービックキューブの回転記号をえる 考え方?
各色9個のブロックがあり それが6面あります
なので 全部で 54個の色を取得するひつようがります。
No.3の記事で色の取得はおわってますので
'red'とかの部分をkociemba用の記号(F,L,R,U,D,B)に書き換えて 下の result_listにねじこみます。
まづ 54個の空リストをつくり そこに インデックスの0-8に黄色、9-17に橙をいれていけばいいのです
result_list = [[] for i in range(54) ]
# [[],[],[],,,,,,,,,[],[]]
# これで空のリストが 54個作成されます。
サンプルコード(kociembaの記号にする 説明)
# 取得した色↓
color_key = ['L','U','F',
'B','U','B',
'B','U','U']
result_list = [[] for i in range(54) ]
# 取得した色を指定の場所へねじこむ(インデックスで指定)
# 0~8
if color_key[4] == 'U':#黄色
result_list[0:9] = color_key
# 9~17
elif color_key[4] == 'R':#橙(オレンジ)
result_list[9:18] = color_key
# 18~26
elif color_key[4] == 'F':#緑
result_list[18:27] = color_key
# 27~35
elif color_key[4] == 'D':#(白)
result_list[27:36] = color_key
# 36~44
elif color_key[4] == 'L':#赤
result_list[36:45] = color_key
# 45~53
elif color_key[4] == 'B':#青
result_list[45:54] = color_key
print(result_list)
# ['L', 'U', 'F', 'B', 'U', 'B', 'B', 'U', 'U', #0-8
[], [], [], [], [], [], [], [], [],#9-17
[], [], [], [], [], [], [], [], [],#18-26
[], [], [], [], [], [], [], [], [],#27-35
[], [], [], [], [], [], [], [], [],#36-44
[], [], [], [], [], [], [], [], []]#44-53
どんなに回しての中心の色がかわることは ないので
中心の色に合わせて追加する 場所をきめています
中心が黄色ならresult_listのインデックスが0-8番目
中心が橙(オレンジ)ならresult_listのインデックスが9-17番目
サンプルコード(kociembaの記号に変える)
import cv2
import time
capture = cv2.VideoCapture(2)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1080) # 横幅
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # 縦幅
result_list = [[] for i in range(54) ]
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]]
color_key = ['black','black','black',
'black','black','black',
'black','black','black']
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
}
# Y縦 X横
frame_xy = [[300, 300],[300, 450],[300, 600],
[450, 300],[450, 450],[450, 600],
[600, 300],[600, 450],[600, 600]]
x_start = [280, 430, 580, 280, 430, 580, 280, 430, 580]
y_start = [280, 280, 280, 430, 430, 430, 580, 580, 580]
x_end = [320, 470, 620, 320, 470, 620, 320, 470, 620]
y_end = [320, 320, 320, 470, 470, 470, 620, 620, 620]
x_start2 = [30, 80, 130, 30, 80, 130, 30, 80, 130]
y_start2 = [30, 30, 30, 80, 80, 80, 130, 130, 130]
x_end2 = [70, 120, 170, 70, 120, 170, 70, 120, 170]
y_end2 = [70, 70, 70, 120, 120, 120, 170, 170, 170]
while True:
ret, frame = capture.read()
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]
cv2.putText(frame, str(k), (xs2, ys2), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 2)
if color_key[k] == 'L':
b1, g1 ,r1 = 0, 0, 255
elif color_key[k] == 'F':
b1, g1 ,r1 = 0, 255, 0
elif color_key[k] == 'D':
b1, g1 ,r1 = 255, 255, 255
elif color_key[k] == 'B':
b1, g1 ,r1 = 255, 0, 0
elif color_key[k] == 'R':
b1, g1 ,r1 = 0, 128, 255
elif color_key[k] == 'U':
b1, g1 ,r1 = 0, 255, 255
#左上に 色を表示する
cv2.rectangle(frame, (xs2, ys2), (xe2, ye2), (int(b1), int(g1), int(r1)), -1)
#BGRの取得位置
for i, (x, y) in enumerate(frame_xy):
pixel = frame[x, y]
b = pixel[0]
g = pixel[1]
r = pixel[2]
BGR = [b,g,r]
color_index[i] = BGR
#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:
#0~8
if color_key[4] == 'U':
result_list[0:9] = color_key
#9~17
elif color_key[4] == 'R':
result_list[9:18] = color_key
#18~26
elif color_key[4] == 'F':
result_list[18:27] = color_key
#27~35
elif color_key[4] == 'D':
result_list[27:36] = color_key
#36~44
elif color_key[4] == 'L':
result_list[36:45] = color_key
#45~53
elif color_key[4] == 'B':
result_list[45:54] = color_key
print(result_list)
time.sleep(0.3)
cv2.imshow('camra',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
capture.release()
cv2.destroyAllWindows()
# サンプルコード(kociembaの記号に変える) を実行 
中心の色が黄色なので 0-8番目に追加されています。
ちなみに ずっとこの処理をするのも どうなのってことなので
TABキーをおしたら 追加するようにしています。
# TAB 取得した色をリストに追加
key3 = cv2.waitKey(1)
if key3 == 9:
kociembaを使う
# python3
pip3 install kociemba
ターミナルでこれすれば できるはずです。だめなら一番上ほうのサイトで確認してみてください
大きくコードはかえてませんが
import cv2
import time
import kociemba
capture = cv2.VideoCapture(0)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1080) # 横幅
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # 縦幅
result_list = [[] for i in range(54) ]
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]]
color_key = ['black','black','black',
'black','black','black',
'black','black','black']
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
}
# Y縦 X横
frame_xy = [[300, 300],[300, 450],[300, 600],
[450, 300],[450, 450],[450, 600],
[600, 300],[600, 450],[600, 600]]
x_start = [280, 430, 580, 280, 430, 580, 280, 430, 580]
y_start = [280, 280, 280, 430, 430, 430, 580, 580, 580]
x_end = [320, 470, 620, 320, 470, 620, 320, 470, 620]
y_end = [320, 320, 320, 470, 470, 470, 620, 620, 620]
x_start2 = [30, 80, 130, 30, 80, 130, 30, 80, 130]
y_start2 = [30, 30, 30, 80, 80, 80, 130, 130, 130]
x_end2 = [70, 120, 170, 70, 120, 170, 70, 120, 170]
y_end2 = [70, 70, 70, 120, 120, 120, 170, 170, 170]
while True:
ret, frame = capture.read()
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]
cv2.putText(frame, str(k), (xs2, ys2), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 2)
if color_key[k] == 'L':
b1, g1 ,r1 = 0, 0, 255
elif color_key[k] == 'F':
b1, g1 ,r1 = 0, 255, 0
elif color_key[k] == 'D':
b1, g1 ,r1 = 255, 255, 255
elif color_key[k] == 'B':
b1, g1 ,r1 = 255, 0, 0
elif color_key[k] == 'R':
b1, g1 ,r1 = 0, 128, 255
elif color_key[k] == 'U':
b1, g1 ,r1 = 0, 255, 255
#左上に 色を表示する
cv2.rectangle(frame, (xs2, ys2), (xe2, ye2), (int(b1), int(g1), int(r1)), -1)
#BGRの取得位置
for i, (x, y) in enumerate(frame_xy):
pixel = frame[x, y]
b = pixel[0]
g = pixel[1]
r = pixel[2]
BGR = [b,g,r]
color_index[i] = BGR
#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:
#0~8
if color_key[4] == 'U':
result_list[0:9] = color_key
#9~17
elif color_key[4] == 'R':
result_list[9:18] = color_key
#18~26
elif color_key[4] == 'F':
result_list[18:27] = color_key
#27~35
elif color_key[4] == 'D':
result_list[27:36] = color_key
#36~44
elif color_key[4] == 'L':
result_list[36:45] = color_key
#45~53
elif color_key[4] == 'B':
result_list[45:54] = color_key
print(result_list)
time.sleep(0.3)
# @キー
key4 = cv2.waitKey(1)
if key4 == 64:
result = ''.join(result_list)
result = kociemba.solve(result)
print(result)
cv2.imshow('camra',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
capture.release()
cv2.destroyAllWindows()
追加したコード
import kociemba
# @キー
key4 = cv2.waitKey(1)
if key4 == 64:
result = ''.join(result_list)
result = kociemba.solve(result)
print(result)
result_list =
['R', 'F', 'D', 'L', 'U', 'U', 'F', 'B', 'L', #0-8 U 中心が黄色
'F', 'L', 'B', 'U', 'R', 'U', 'B', 'D', 'L', #9-17 R 中心がオレンジ
'U', 'D', 'D', 'R', 'F', 'B', 'R', 'D', 'L', #18-26 F 中心が緑
'U', 'F', 'U', 'D', 'D', 'L', 'D', 'L', 'F', #27-35 D 中心が白
'D', 'F', 'R', 'R', 'L', 'U', 'L', 'R', 'B', #36-44 L 中心が赤
'R', 'R', 'F', 'F', 'B', 'B', 'U', 'B', 'B'] #45-53 B 中心が青
# @キー
key4 = cv2.waitKey(1)
if key4 == 64:
result = ''.join(result_list)
result = kociemba.solve(result)
print(result)
全部のキューブの色を取得して@キーをおすと
kociemba.solve()で 下の回転記号がでてきます
U' D2 R2 U' B2 L2 B' U' F R' B L2 B2 R2 D B2 D' L2 U2 F2 L2