深層学習とYOLOを活用したスマートフルーツ検査システムの実装
はじめに
消費者にとって、果物の品質は選択と健康に直結する重要な要素です。従来の目視検査は効率が低く、人為的誤差の影響を受けやすいという欠点があります。深層学習技術を導入することで、高速かつ自動化された果物品質検査を実現できます。
本記事では、YOLO(You Only Look Once)モデルを用いたフルーツ品質検出システムの構築プロセスを、システム設計からモデルトレーニング、デプロイまで網羅的に解説します。
システム設計とアーキテクチャ
本システムは、ユーザーインターフェース(UI)、バックエンドAPI、およびYOLO検出モデルの3つの主要コンポーネントで構成されます。ユーザーはUIを通じて果物の画像をアップロードし、バックエンドがYOLOモデルを呼び出して検出を行い、その結果をユーザーに返却します。
+------------------+ +--------------+ +-----------------+ | ユーザーインターフェース | <----> | バックエンドAPI | <----> | YOLO検出モデル | +------------------+ +--------------+ +-----------------+
フロントエンドの実装
UIはReact.jsフレームワークを使用して構築します。主要な機能は画像アップロードと検出結果の表示です。
Reactコンポーネント(画像アップロード)
// ImageUploader.js
import React, { useState } from 'react';
const ImageUploader = ({ onImageUpload }) => {
const [selectedFile, setSelectedFile] = useState(null);
const handleFileChange = (event) => {
setSelectedFile(event.target.files[0]);
};
const handleSubmit = (event) => {
event.preventDefault();
if (selectedFile) {
onImageUpload(selectedFile);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="file" accept="image/*" onChange={handleFileChange} />
<button type="submit">画像をアップロードして検出</button>
</form>
);
};
export default ImageUploader;
バックエンドの実装
バックエンドはFlaskフレームワークで構築し、画像受信とモデル呼び出しのAPIエンドポイントを提供します。
Flaskサーバー
# api_service.py
from flask import Flask, request, jsonify
import detect_logic # カスタム検出ロジックをインポート
app = Flask(__name__)
@app.route('/api/detect', methods=['POST'])
def detect_fruit():
if 'image' not in request.files:
return jsonify({'error': '画像ファイルがありません'}), 400
file = request.files['image']
# 検出ロジックを呼び出し
result = detect_logic.analyze_fruit(file)
return jsonify(result)
if __name__ == '__main__':
app.run(debug=True, port=5001)
データ準備
モデルのトレーニングには、大量のフルーツ画像とそのアノテーションデータが必要です。
データセットの収集と前処理
公開データセットから画像を収集し、LabelImgなどのツールでバウンディングボックスを付与します。その後、YOLO形式に変換します。
# annotation_converter.py
import os
import xml.etree.ElementTree as ET
def convert_voc_to_yolo(voc_dir, yolo_dir, classes):
# VOC形式のアノテーションファイルをYOLO形式に変換するロジック
for xml_file in os.listdir(voc_dir):
if not xml_file.endswith('.xml'):
continue
tree = ET.parse(os.path.join(voc_dir, xml_file))
root = tree.getroot()
size = root.find('size')
width = int(size.find('width').text)
height = int(size.find('height').text)
yolo_lines = []
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
xmin = float(xmlbox.find('xmin').text)
ymin = float(xmlbox.find('ymin').text)
xmax = float(xmlbox.find('xmax').text)
ymax = float(xmlbox.find('ymax').text)
x_center = (xmin + xmax) / 2.0 / width
y_center = (ymin + ymax) / 2.0 / height
box_width = (xmax - xmin) / width
box_height = (ymax - ymin) / height
yolo_lines.append(f"{cls_id} {x_center} {y_center} {box_width} {box_height}")
# YOLO形式のテキストファイルに書き出し
with open(os.path.join(yolo_dir, xml_file.replace('.xml', '.txt')), 'w') as f:
f.write('
'.join(yolo_lines))
モデルの選択とトレーニング
YOLOモデルの概要
YOLOはリアルタイム物体検出に優れたパフォーマンスを発揮するモデルです。YOLOv8は最新バージョンとして、精度と速度のバランスが優れています。
環境設定とトレーニング
# 環境設定
pip install -r yolov8/requirements.txt
# データセットの分割
python split_dataset.py --source data/images --output data/split --train 0.8 --val 0.1 --test 0.1
# モデルのトレーニング
python yolov8/train.py \
--img 640 \
--batch 32 \
--epochs 100 \
--data data.yaml \
--cfg yolov8n.yaml \
--weights yolov8n.pt \
--name fruit_detection_v8
モデルのデプロイ
トレーニング済みモデルを本番環境で利用するため、Dockerコンテナを用いてTensorFlow Servingでデプロイします。
# モデルのエクスポート(例: ONNX形式)
python export_model.py --weights best.pt --img-size 640 --opset 12
# Dockerを使用したデプロイ
docker pull tensorflow/serving
docker run -p 8501:8501 \
--name fruit_inspection_serving \
-v /path/to/your/model:/models/fruit_model \
-e MODEL_NAME=fruit_model \
-t tensorflow/serving
システムテスト
システムの機能とパフォーマンスを確認するため、単体テスト、統合テスト、および負荷テストを実施します。Flaskのテストクライアントを使用してAPIエンドポイントをテストしたり、JMeterなどのツールで同時リクエスト数を増やして応答時間を測定したりします。