eyetoy(USBカメラ)写真から色識別！！OpenCVを用いて色抽出

#下準備
##必要なもの
・raspberryPI×１
・eyetoy(usbカメラ、webカメラ)×２

##いまさらeyetoyで写真を撮る意味とは
今回、eyetoyを採用した最大の理由は~~SONYが盛大に失敗したために~~とても安いからです。
しかも本来はPS2用ガジェットとして売り出された本製品は、専用ソフトもあまり売れずに過去の産物としてBook offなどでは大体100円の捨て値で販売されているから手が出しやすいですね！！



##OpenCVをインストール
色識別、マウスイベントを読み取るためのインストールします。

https://qiita.com/mt08/items/e8e8e728cf106ac83218
の方法を用いてインストールすることをおすすめします。
~~まじでインストールする方法探すの時間かかりすぎてめんどくさかった~~


#OpenCVを使ってUSBカメラで写真を撮る
$ ls -al /dev
↑とターミナルで打ち込むと、「video0」と表示されてるデバイスがあると思いますが、それがカメラのことです。 

あと、**あらかじめ「capture」フォルダを製作**しておいてください

```python3:camera_test.py'
import cv2


fileName = "/home/pi/capture/_1_cv2.jpg"
print(fileName)


capture = cv2.VideoCapture(0)
#カメラにアクセス、カッコ内はコマンドの数字


ret,image = capture.read()
#画像を読み込む


w = image.shape[0]
h = image.shape[1]
print("高さ" + str(w))
print("幅は" + str(h))

if ret == True:
    cv2.imwrite(fileName,image)
#if image == True: だとエラーが起きるからよく使われてるretとかがいいと思います


cv2.imwrite("/home/pi/capture/_1_cv2.jpg",image)
cv2.namedWindow("/home/pi/capture/_1_cv2.jpg", cv2.WINDOW_NORMAL)
cv2.imshow("/home/pi/capture/_1_cv2.jpg", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#WINDOW_NORMALはウィンドウサイズを変更可能にする
#inshowはウィンドウ上に表示する関数
#waitkeyはキーボードの入力待ちで、()内待ち時間をミリ秒で指定できる。0は無期限
#destroyAllWindowsは現在までに作られたウィンドウをすべて閉じる。また、指定できる。
```

#写真の座標の色を抽出、識別させる

##色を識別させる座標を確認する
20ピクセルづつ赤青交互に線が引かれています。
赤線だけなら40ピクセルづつ、青線だけなら一本目だけ20ピクセルからはじまって40ピクセルづつ線が引かれています。
赤線5本で緑線1本、つまり200ピクセルおきに緑線が引かれています。
これをコピペして使って、線を数える事で大体の座標がわかると思うので色を識別したい座標を調べといてください。

```python:color_coordinate.py
import cv2

img = cv2.imread("/home/pi/capture/_1_cv2.jpg",1)
#-1はRGBA(RGB+透明度),0はグレースケール,1はRGB

h = img.shape[0]
w = img.shape[1]
#画像の高さ(height)と幅(width)を取得

n = 0#(number)公差40とするための変数
k = 0#(kazu)初項20とするための変数
f = 0#(fievline)赤線が5本引かれた場合のみ出現する線の変数

#初項0,公差40の等差数列を赤線で記す
#初項20,公差40の等差数列を青線で記す
cv2.line(img,(0,0),(0,h),(0,0,225),1)#(0,0)~(0,h)の間に赤線を太さ1で引く
cv2.line(img,(0,0),(w,0),(0,0,255),1)#(0,0)~(w,0)の間に赤線を太さ1で引く
#RGB順ではなくBGR順になってる事に注意

cv2.line(img,(20,0),(20,h),(255,0,0),1)
cv2.line(img,(0,20),(w,20),(255,0,0),1)
#青線と赤線が交互になるように20ピクセル進んだところからスタート


while(n < w):
#フレームの最後まで等差数列の処理をする

    n += 40
    k = n + 20
    f = n/10

    if f%5 == 0:
    #fが5の倍数の時に行う処理
        cv2.line(img,(n,0),(n,h),(0,255,0),1)
        cv2.line(img,(0,n),(w,n),(0,255,0),1)
        cv2.line(img,(k,0),(k,h),(255,0,0),1)
        cv2.line(img,(0,k),(w,k),(255,0,0),1)
    #fが5の倍数でない場合の処理
        cv2.line(img,(n,0),(n,h),(0,0,225),1)
        cv2.line(img,(0,n),(w,n),(0,0,255),1)
        cv2.line(img,(k,0),(k,h),(255,0,0),1)        
        cv2.line(img,(0,k),(w,k),(255,0,0),1)
        #ここらへんの説明については[文献2]をご覧ください
        
cv2.namedWindow("/home/pi/capture/_line_cv2.jpg", cv2.WINDOW_NORMAL)
cv2.imshow("/home/pi/capture/_line_cv2.jpg", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#WINDOW_NORMALはウィンドウサイズを変更可能にする
#inshowはウィンドウ上に表示する関数
#waitkeyはキーボードの入力待ちで、()内待ち時間をミリ秒で指定できる。0は無期限
#destroyAllWindowsは現在までに作られたウィンドウをすべて閉じる。また、指定できる。
```
参考文献は[こちら](#bunken)

##座標の色を識別する
色を数値化するときは、**RGB**を用いるのが一般的で、Red,Green,Blueを最大255段階に分けることで識別することができる方法です。

例えば、[0,0,255]で「青」と答えが返ってくるならまだしも、現実はそう優しくないので[0,0,100]で「青」とか言われちゃうわけです。
そうなると**色を判別する条件が複雑になります。**
飽きっぽい作者のブログ更新はなくなりますね。むりぽよ(´・ω・｀)

そこで、**HSV**と呼ばれる方法で数値化すれば問題解決しちゃうわけです。
色相、彩度、明度の三つの成分から成り立っているんですね！
色相は環状になっているので、**色を判断する条件が簡単になります**

なのでここでは、**RGBで色情報を受け取って、HSVに変換する作業を行います**

```RGB_to_HSV_test.py
import cv2
import colorsys

img = cv2.imread('/home/pi/capture/_1_cv2.jpg')
#画像を読み込む

bgr = img[260,460]
#bgr = img[縦の行,横の行]

print('rbgの結果'+ str(bgr) )
#「文字列＋変数」で出力するときは　str(変数)　とする
#RGB順ではなく、BGR順に出力されるから注意！！

num = bgr[0:3]
#[文献3]のリストの欄を参照されたし！！

hsv = colorsys.rgb_to_hsv(bgr[2],bgr[1],bgr[0])
#偉い大人たちがたくさんの色変換の方法を考え抜いてくれた[文献4]
print('hsvの結果'+ str(hsv) )
```

#参考文献<a name="bunken"></a>
[文献1]https://qiita.com/mt08/items/e8e8e728cf106ac83218
[文献2]http://rasp.hateblo.jp/entry/2016/01/24/135417
[文献3]http://www.tohoho-web.com/python/list.html#list
[文献4]https://docs.python.jp/3/library/colorsys.html