OpenCV Pythonを使ったぼけ写真判定と除外など
作ろうと思ったきっかけ
写真を撮った後、
連写で撮った写真のどれを残すか
連写、単写を問わず、同じような写真が多数あって、投稿する場合、どれにするか。
1)
明らかなぼけ写真で、カメラのファインダーでもわかるのは、カメラの機能で消す。(この場合、SONYが断トツに便利、NIKONもFUJI FILMもだめ、但し自分にとっては)
2)
PC,または大型タブレットで見て、地道に消して行く
3)
最近の場合は、Image Canon なんかのぼけ判定を使う
などなど、だれでも行われてると思います。
枚数が少ないうちは、お時間に余裕がある場合は、これも撮影と同じく楽しい作業かと思います。
枚数が多い場合、お仕事でされてる場合など、速く済ませたいですね。
というわけで、ネットで調べると、
1) 野球関係プロカメラマン御用達のぼけ判定除外ツール
2) 運動会お子様写真のかんたんボケ判定
など、ありました。
Image Canon 使えば即解消なのかどうか、わからない、Canonの最近のカメラがないまたは買えない自分なので、
OpenCV + Python で自作しました。
コード例
バックエンドのPHPでリクエスト受けて、
Shellで下のPython呼んで、一時テキストファイルに出力
Python シャープネス値取得シェルとPHPです。
シャープネス値はMySQLのテーブルの列に保存するので、どっからでも必要に応じて使える。
"""
写真ファイル名指定ぼけ判定
File name : BokeDetect.py
0に近いほどボケていると言える。
数値が大きいほど鮮明
すなわち、 誤解されるでえ。。。。
なので、GetSharpnessAndCreateTmpFile あたりがふさわしい
が、そのまま
First create :
Last update :
"""
import sys
import cv2
# 結果出力ファイル名 #
TMP_FILENAME = "tmp_cv2_info.txt"
f = open(TMP_FILENAME, 'w')
f = open(TMP_FILENAME, 'a')
# 画像ファイル名が第一引数 #
args = sys.argv
fnm = args[1]
# 画像を呼んでオブジェクトに入れる #
img = cv2.imread(fnm)
# 画像のシャープネス値取得 #
p = cv2.Laplacian(mg, cv2.CV_64F).var()
s = "ボケ程度:%f" % p
print(s)
# 一時ファイルに書き込み #
f.write(str(p))
f.close()
<?php
/**
* アップロード写真ぼけ度(シャープネス)更新
*
*/
include '../DefaultHeaderIni.php';
include '../MySQLConnectConfig_aviation.php';
ini_set('display_errors', 1);
// ================================================== //
// 対象検索 //
$SQL_SELECT = <<<EOM
SELECT
a.ID,
REPLACE(a.URL_ORIGINAL, 'https://??????????', '/?????????/') AS FILENAME_IMG,
a.TM_ADD, a.TM_UPDT
FROM
m_photo_userstatus a
WHERE
DEG_BOKE = 0
OR
a.ID IN (
SELECT
ID_PHOTO
FROM log_photo_modify m
WHERE
m.TM_ADD > DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -12 MINUTE)
)
EOM;
// 更新 //
$SQL_UPDATE = <<<EOM
UPDATE m_photo_userstatus
SET DEG_BOKE = :DEG_BOKE
WHERE ID = :ID
EOM;
// Shell実行ファイル //
$DETECT_PYTHON = "./python/BokeDetect.py";
// ================================================== //
try {
//データベース接続 //
$dbh = new PDO(
$connect_db,
$connect_user,
$connect_passwd
);
// 対象画像ファイルリスト取得 //
$stmt = $dbh->query($SQL_SELECT);
$files = array();
$ids = array();
// ++ 配列追加 ++ //
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$files[] = $row["FILENAME_IMG"];
$ids[] = $row["ID"];
}
// ++ 検出、テーブル更新 ++ //
$pos = 0;
foreach ($files as $file) {
echo "------------ " . $pos . "/" . strval(count($files)) . " ---------------" . PHP_EOL;
if (file_exists($file)) {
// Shell実行 //
$cmd = "python " . $DETECT_PYTHON . " " . $file;
exec($cmd, $output, $state);
var_dump($cmd);
// 結果テキストファイル読込 //
$res_textfile = "tmp_cv2_info.txt";
$restxt = file_get_contents($res_textfile);
var_dump($restxt);
$resval = (double) $restxt;
var_dump($resval);
var_dump($ids[$pos]);
// テーブル更新 //
$stmtu = $dbh->prepare($SQL_UPDATE);
$stmtu->bindvalue(':ID', $ids[$pos], PDO::PARAM_INT);
$stmtu->bindvalue(':DEG_BOKE', $resval);
$stmtu->execute();
}
$pos++;
}
}
catch (PDOException $e) {
//var_dump($e->getMessage());
$updtres = "Fail";
}
結果
画像サンプルは今のところ面倒くさいので省略。
自分のニーズに対しては、「まだ使い物にならない」
なるほど、
勘と経験を排除した最新技術を駆使した画像処理でもって、見える化、数値化出来て、効率化達成、バンザイ
とIT系有名企業の言うセールス、ユーザーエクスペリエンスの喚起達成と言いたいところ、
問題としては、
1)
飛行機の場合、飛行機のみで雲も同じ状態の連写では高低を判断してえる。
2)
同じく飛行機の場合、飛行機のぼけだけで判定したいのに、背景(木々、電線、構造物など)飛行機と一緒に写ってるのも同じぼけ判定の対象になり、
結果、飛行機がぼけてるのに木々、電線、構造物が入ってると値が高い(クッキリですよと機械が言ってくれる)
3)
PC, タブレットで改変処理(Windows Photo, IrfanViewとか使って)してシャープネス上げた画像は、異常に高い判定値となってしまう。
(クッキリですよと機械が言ってくれる)
これから
多分、AIで飛行機や鳥、人だけを切り取り、それを判定させればよいと思うが、
DUE TO PERFOTMANCE,
DUE TO NO TIME
今のところ、必要ない。
が理由で何もしない。