ラズパイとカメラを使用してカラーセンサー作成

#要望　加工品のつまり、終了を見抜きたい
機械工作工場にて自動レーンでの製品のつまり、最終加工品の完了した時を知りたい。
![製品のつまり.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695230/448d4644-a84f-d782-286d-0d500cbdcb74.jpeg)
バルブの赤いハンドルの位置（開閉表示）を知りたい。
![バルブの状態.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695230/f9fdc365-a49d-f83a-874d-a7d4d8d7dd7b.png)

製品は黄色、背景（レーン）は白、青、又は黒の原色。
既製品のセンサーが高すぎるので安く作って欲しいとの要望。

#完成品
ラズパイをローカルWIFIにつなげて。
http://"ラズパイのIPアドレス"/home.php

![加工品.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695230/5bf7790c-9649-805e-55ab-1557236a623e.jpeg)

![抜き出し場所.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695230/f3afad37-370c-fc8f-b3e9-7817052f11b5.jpeg)

カメラ画像から当該箇所を指定して抜き出す。
色範囲を指定して、色範囲に入った場合GPIOを出力する。
GPIOの出力にて警報ランプを起動させる。
警報解除は警報リセットにて行う。

#ラズパイ環境設定
python OpenCV　ダウンロード
[参考サイト　計算機科学を学んだソフトウェア技術者の経験やメモなどの記録様](http://my-web-site.iobb.net/~yuki/2017-09/raspberry-pi/capture/)

```sudo apt-get install libopencv-dev```
```sudo apt-get install python-opencv```

アパッチダウンロード
[参考サイト　@mono_taro様](https://qiita.com/mono_taro/items/c4f6dfed115c30d0eef6)
```sudo apt-get update```
```sudo apt-get upgrade```
```sudo apt-get install apache2```
```apachectl -v```

phpダウンロード
[参考サイト　The modern stone age.様](https://www.yokoweb.net/2018/05/12/ubuntu-18_04-apache2-php72/)
```sudo apt install php7.2 libapache2-mod-php7.2```

#php及びhtml作成
```ruby:/var/www/html/home.php
<html>
<head>
<meta http-equiv="content-type" charset="utf-8">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="refresh" content="5" >
</head>
</html>
<form action="set.php" method="get">
<body>
	<h1>カメラ画像</h1>
	<?php
		$lines_reset = file('/home/pi/Documents/reset.csv');
		foreach($lines_reset as $line_reset){
			$data_reset = explode(',',$line_reset);
		if ($data_reset[0] == 1){
		echo "<FONT COLOR=\"RED\"> 現在警報動作中 解除する場合は下ボタンにて </FONT>";}
		}
	?>
		<img src="1.jpg?1">
		<h2>抜出画像</h2>
		<img src="2.jpg?1">
</body>
<?php
$lines = file('/home/pi/Documents/color.csv');
foreach($lines as $line){
	$data = explode(',',$line);	
	echo '<p>';
	echo ' 赤色R',$data[0];
	echo ' 緑色G：',$data[1];
	echo ' 青色B：',$data[2];	
	echo '</p>';
}
?>
<a href="./set.html">設定画面</a>
<a href="./reset.html">警報リセット</a>
</form>
```
```ruby:/var/www/html/set.html
<form action="set.php" method="get">
<p>
<a href="./home.php">戻る</a>
</p>
<img src="1.jpg">
<p>色の範囲指定</p>
<p>赤下限: <input type="number" name="r_2_1" value="1" min="0" max="255"></p>
<p>赤上限: <input type="number" name="r_2_2" value="1" min="0" max="255"></p>
<p>緑下限: <input type="number" name="g_2_1" value="1" min="0" max="255"></p>
<p>緑上限: <input type="number" name="g_2_2" value="1" min="0" max="255"></p>
<p>青下限: <input type="number" name="b_2_1" value="1" min="0" max="255"></p>
<p>青上限: <input type="number" name="b_2_2" value="1" min="0" max="255"></p>
<p>画像抜出ファイル　上下は上からの距離、左右は左からの距離</p>
<p>上top: <input type="number" name="top" value="1" min="0" max="2000"></p>
<p>下bot: <input type="number" name="bot" value="100" min="0" max="2000"></p>
<p>左left: <input type="number" name="left" value="1" min="0" max="2000"></p>
<p>右right: <input type="number" name="right" value="100" min="0" max="2000"></p>
<p>シャッター間隔、規定回数</p>
<p>シャッター間隔　秒（ｓ）: <input type="number" name="interval" value="60" min="10" max="6000"></p>
<p>回数: <input type="number" name="nutime" value="1" min="1" max="100"></p>
<input type="submit" />
<p>　</p>
<p>補足色説明</p>
<p>赤色　R255 G0 B0</p>
<p>黒　R0 G0 B0</p>
<p>白　R255 G255 B255</p>
<p>黄色　R255 G255 B0</p>
<p>灰色　R128 G128 B128</p>
<p>その他の色はRGB色で検索願います。</p>
<p>規定回数とは連続で指定範囲内に入った回数の時、リレーが作動する回数</p>
</form>
```

```ruby:/var/www/html/set.php
<meta http-equiv="content-type" charset="utf-8">
<?php 
     $r_2_1=htmlspecialchars($_GET["r_2_1"],ENT_QUOTES);
     $r_2_2=htmlspecialchars($_GET["r_2_2"],ENT_QUOTES);
     $g_2_1=htmlspecialchars($_GET["g_2_1"],ENT_QUOTES);
     $g_2_2=htmlspecialchars($_GET["g_2_2"],ENT_QUOTES);
     $b_2_1=htmlspecialchars($_GET["b_2_1"],ENT_QUOTES);
     $b_2_2=htmlspecialchars($_GET["b_2_2"],ENT_QUOTES);
     $top=htmlspecialchars($_GET["top"],ENT_QUOTES);
     $bot=htmlspecialchars($_GET["bot"],ENT_QUOTES);
     $left=htmlspecialchars($_GET["left"],ENT_QUOTES);
     $right=htmlspecialchars($_GET["right"],ENT_QUOTES);
     $interval=htmlspecialchars($_GET["interval"],ENT_QUOTES);
     $nutime=htmlspecialchars($_GET["nutime"],ENT_QUOTES);
?>
<body>
<?php echo $_GET["r_2_1"]; ?>
<?php 
$data = [
    [$_GET["r_2_1"], $_GET["r_2_2"], $_GET["g_2_1"], $_GET["g_2_2"], $_GET["b_2_1"], $_GET["b_2_2"],
    $_GET["top"], $_GET["bot"], $_GET["left"], $_GET["right"],
    $_GET["interval"], $_GET["nutime"]],
];
$fp = fopen('/home/pi/Documents/position.csv', 'w');
foreach ($data as $line) {
	fputcsv($fp, $line);
}
fclose($fp);
?>
<p>
<a href="./home.php">戻る</a>
</p>
```

```ruby:/var/www/html/reset.html
<meta http-equiv="content-type" charset="utf-8">
<meta http-equiv="Cache-Control" content="no-cache">
<form action="reset.php" method="get">
<input type="submit" />
</form>
```

```ruby:/var/www/html/reset.php
<meta http-equiv="content-type" charset="utf-8">
<?php 
$data = [["0"]];
$fp = fopen('/home/pi/Documents/reset.csv', 'w');
foreach ($data as $line) {
	fputcsv($fp, $line);}
fclose($fp);
?>
<p>
<a href="./home.php">戻る</a>
</p>
```

#python 及びCSV作成

```ruby:/home/pi/Documents/gazou.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cv2, os
import numpy as np
import csv
import time
import RPi.GPIO as GPIO
time.sleep(60)#ラズパイ起動時の待機時間
#GPIO設定
PIN = 14
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.OUT)
#イメージファイルの保存場所
image_file = '/var/www/html/1.jpg' #写真撮影
image_file_2 = '/var/www/html/2.jpg' #検証１
#読み込み用CSVの場所
poss = '/home/pi/Documents/position.csv'
colo_0 = '/home/pi/Documents/color0.csv'
colo_1 = '/home/pi/Documents/color.csv'
poss_reset = '/home/pi/Documents/reset.csv'
while True:
	try :
		with open(poss) as data0:#切り出し場所を読み取る
			reader = csv.reader(data0)
			data1 = [row for row in reader]
		#範囲読み取り
		r_2_1 = int(data1[0][0]) #赤下限 img2
		r_2_2 = int(data1[0][1]) #赤上限 img2
		g_2_1 = int(data1[0][2]) #緑下限 img2
		g_2_2 = int(data1[0][3]) #緑上限 img2
		b_2_1 = int(data1[0][4]) #青下限 img2
		b_2_2 = int(data1[0][5]) #青上限 img2
		#img2.jpgの切り出し部分
		top_2   = int(data1[0][6])
		bot_2   = int(data1[0][7])
		left_2  = int(data1[0][8])
		right_2 = int(data1[0][9])
		#繰り返し秒数及び動作確認数
		jobs_s = int(data1[0][10])
		time.sleep(jobs_s)
		with open(poss_reset) as data_reset:#リセットCSV読み取り
			reader_reset = csv.reader(data_reset)
			data_reset1 = [row for row in reader_reset]
		data_resset2 = int(data_reset1[0][0])
		with open(colo_0) as data2:#書き込み用のデフォルトデータを読み込む
			reader = csv.reader(data2)
			data3 = [row for row in reader]
		cam = cv2.VideoCapture(0)
		# カメラから映像を読み込む
		_, img = cam.read()
		# 画像ファイルとして書き出す
		img2 = img[top_2 : bot_2, left_2: right_2]
		#イメージ保存
		cv2.imwrite(image_file, img)
		cv2.imwrite(image_file_2, img2)
		# RGB平均値を出力
		# flattenで一次元化しmeanで平均を取得 
		r2 = img2.T[2].flatten().mean()
		g2 = img2.T[1].flatten().mean()
		b2 = img2.T[0].flatten().mean()		
		if data_resset2 == 0:
			GPIO.output(PIN, GPIO.LOW) #とりあえず切る
			if r_2_1 < r2 < r_2_2 and g_2_1 < g2 < g_2_2 and b_2_1 < b2 < b_2_2:
				GPIO.output(PIN, GPIO.HIGH)
				data_resset2 = 1
		# RGB平均値を取得
		data3[0][0] = '%.0f' % r2
		data3[0][1] = '%.0f' % g2
		data3[0][2] = '%.0f' % b2
		#CSVを保存
		with open(colo_1, 'w') as f:
			writer = csv.writer(f)
			for data4 in data3:
				writer.writerow(data4)
		data_reset1[0][0] = data_resset2
		with open(poss_reset, 'w') as f:
			writer = csv.writer(f)
			for data_reset2 in data_reset1:
				writer.writerow(data_reset2)
		# 事後処理
		cam.release()
		cv2.destroyAllWindows()
	except:
		time.sleep(30)
		pass
```
```ruby:/home/pi/Documents/position.csv
1,1,1,1,1,1,1,100,1,100,60,1
```
```ruby:/home/pi/Documents/color0.csv
100,100,100,100,100,100
```
```ruby:/home/pi/Documents/color.csv
100,100,100,100,100,100
```
```ruby:/home/pi/Documents/reset.csv
0
```

#起動時にpythonを起動する設定をする。
sudo にて gazou.pyを自動起動する。
sudo でないと/var/www/html/にjpgの画像を書き込まない
[参考サイト@yuru-camper様](https://qiita.com/yuru-camper/items/33b8d8a4900b77edb64d)

#使用したカメラ
C270N HD WEBCAM
[logicool様サイト](https://www.logicool.co.jp/ja-jp/product/hd-webcam-c270n)

#将来やりたい事
設定画面が下記のように設定しにくいので抜き出し箇所はマウスで選択できるようにしたい。
色設定もマウスで決定できるようにしたい。
現在の状態だと設定がトライアンドエラーをたくさん繰り返さなくてはいけない。
![設定画面.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695230/6ec0d0e5-d4e0-15e9-0874-9ffe2d5184a1.jpeg)