今回は人工知能を使い画像から人物や物を見つけ出すプログラムを作ってみました。

ライブラリではCocoSSDという学習済みの物体検出モデルを利用しています。

上記の画像では我が家のバラの画像を読み込んでみました。

88%の信頼でpotted plant「観葉植物」と表示されています。

ちなみに最少スコアの数値を小さくすることによって信頼度が低くてもその物体だとみなすようになります。

sample~

http://ringo-apple-web.com/html/object_detection.html


 <!DOCTYPE html>
 <html>
 <head>
 	<meta charset="utf-8">
 	<title>物体検出</title>
 	<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
 	<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script>
 	<script>
 		let canvas,context; //キャンバス
 		const image = new Image(); //画像
 		let objectLabel = new Array(); //検出した物体のラベル

 		const init = () => {
 			//キャンバス
 			canvas = document.getElementById("image"); //キャンバス147行目取得
 			context = canvas.getContext("2d");
 			//検出ボタンを無効
 			document.getElementById("detectButton").disabled = true;
 		}

 		const loadImage = files => {
 			//画像の読み込み
 			image.src = URL.createObjectURL(files[0]);
 			image.onload = () => {
 				//画像を描画(縦横最大600ピクセル)
 				let width,height,size = 600;
 				if (image.width > image.height) {
 					[width,height] = [siz,image.height/image.width * size];
 				} else {
 					[width,height] = [image.width/image.height * size,size];
 				}
 			[canvas.width,canvas.height] = [width,height];
 			context.clearRect(0,0,width,height);
 			context.drawImage(image,0,0,width,height);
 			//検出結果をクリア、「検出ボタン」を有効
 			document.getElementById("list").innerHTML = "";
 			document.getElementById("message").innerText = "";
 			document.getElementById("detectButton").disabled = false;
 			}
 		}

 		const detect = () => {
 			//検出
 			const minScore = document.getElementById("min").value / 100; 
 			document.getElementById("list").innerHTML ="";
 			objectLabel = [];
 			const message = document.getElementById("message");
 			message.innerText = "検出中.....";
 			cocoSsd.load().then(model => {
 				model.detect(canvas,100,minScore).then(predictions => {
 					for (let i = 0; i<predictions.length; i++) {
 						addObject(predictions[i]);
 					}
 					message.innerText += "完了";
 					if (predictions.length == 0) {
 						message.innerText = "検出されませんでした。";
 					}
 				})
 			})
 		}

 		const addObject = prediction => {
 			//検出した物体のラベルを追加
 			if (objectLabel.indexOf(prediction.class) == -1) {
 				objectLabel.push(prediction.class);
 				const label = document.createElement("div");
 				label.innerText = prediction.class;
 				label.className = "label";
 				document.getElementById("list").appendChild(label);
 				const object = document.createElement("div");
 				object.id = prediction.class;
 				document.getElementById("list").appendChild(object);
 			}
 			//検出した情報を取得
 			const [x,y,w,h] = prediction.bbox;
 			const scale = image.width /canvas.width;
 			const[x1,y1,w1,h1] =  [x * scale,y * scale,w * scale,h * scale];
 			const score = (prediction.score * 100). toFixed(2);
 			//スコア
 			const div = document.createElement("div");
 			div.className = "block";
 			const scoreDiv = document.createElement("div");
 			scoreDiv.innerText  = `(${score}%)`;
 			div.appendChild(scoreDiv);
 			//画像
 			const miniCanvas = document.createElement("canvas");
 			const miniContext = miniCanvas.getContext("2d");
 			let w2,h2,size = 100;
 			if (w > h) {
 				[w2,h2] = [size,h/w * size];
 			} else {
 				[w2,h2] = [w/h * size,size];
 			}
 			miniCanvas.width = w2;
 			miniCanvas.height = h2;
 			miniContext.drawImage(image,x1,y1,w1,h1,0,0,w2,h2);
 			//マウスカーソルが入ったときに検出した短形を描画
 			miniCanvas.onmouseenter = () => {
 				miniCanvas.classList.add("select");
 				context.strokeStyle = "#00CCFF";
 				context.lineWidth = 4;
 				context.strokeRect(x,y,w,h);
 			}
 			//マウスカーソルが出たとき短形を消去
 			miniCanvas.onmouseleave = () => {
 				miniCanvas.classList.remove("select");
 				context.clearRect(0,0,canvas.width,canvas.height);
 				context.drawImage(image,0,0,canvas.width,canvas.height);
 			}
 			div.appendChild(miniCanvas);
 			document.getElementById(prediction.class).appendChild(div);
 		}
 	</script>
<style>
	input[type="number"] {width: 40px;}
	#message {color: #009900;}
	canvas {border: 4px solid #CCCCCC;}
	#image {
		float: left;
		margin-right: 5px;
	}
	#list {
		height: 600px;
		overflow: auto;
	}
	.label {
		padding-left: 5px;
		color: #FFFFFF;
		background-color:  #0000FF;
	}
	.block {
		display: inline-block;
		margin: 0px 10px;
		text-align: center;
		vertical-align: top;
	}
	.select {border: 4px solid #00CCFF;}
</style>
</head>
 <body onload="init()">
 	<p>物体検出verりんご</p>
 	<input type="file" accept="image/*" onchange="loadImage(this.files)">
 	最小スコア:<input type="number" id="min" value="50" min="1" max="100">%
 	<input type="button" id="detectButton" value="検出" onclick="detect()">
 	<span id="message"></span>
 	<hr>
 	<canvas id="image"></canvas>
 	<div id="list"></div> 
 </html>

返事を書く

Please enter your comment!
Please enter your name here

CAPTCHA