LoginSignup
0
0

More than 1 year has passed since last update.

NO.4 ルービックキューブの回転記号をえる

Last updated at Posted at 2021-06-12

ルービックキューブの回転記号をえる

複数の記事になります。 
ルービックキューブの色を取得して kociembaを利用して
最後は回転記号を取得します。

NO.1 カメラ起動+BGR取得
NO.2 ウィンドウに取得した色を表示
NO.3取得したいろが 何色なのか 区別する
NO.5 最終コード 参考程度に,,,,





kociembaを使います
参考、こちらはkociiemba

ルービックキューブの色を取得して kociembaを使えば 回転記号を得られます

参考、こちらは回転記号

kociembaをわかりやすくしてくれてます
kociembaの使い方として 
こちらでも 説明されてる 通り ルービックキューブを 展開してかんがえる必要があります。
ルービックキューブを展開するとこんなかんじ
(日本配色と世界配色でルービックキューブの色の配置が違うので注意してください *これは世界配色)
NO.4 サンプル1.PNG
緑が正面だとすると
緑: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の記号に変える) を実行

NO.4 サンプル3.PNG

中心の色が黄色なので 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
NO.4 サンプル4.PNG

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0