見出し画像

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
今のところ、必要ない。
が理由で何もしない。



いいなと思ったら応援しよう!