画像処理は門外漢ですが、python detect color image
でググると以下がヒットしました。
Detect if image is color, grayscale or black and white with Python/PIL
上記を丸パクリし元に判定関数を作成してみました。
見た目では分からない程度でも色味に揺らぎがあるとカラーと判定されます。
よって実際の運用では、いきなりファイル削除せずに画像をフォルダに振り分けしてMaybe Color
な画像は
MAYBE_COLOR値をあげながら徐々に絞り込むような処理が必要かと思います。
※モデル:レナ姐さん
Python
1import cv2
2import numpy as np
3import os
4
5# モノクロ画像に変換
6def to_gray(path):
7 img = cv2.imread(path)
8 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
9 cv2.imwrite(os.path.splitext(path)[0] + '_gray.jpg', gray)
10
11# 彩度を変更
12def conv_saturation(path,sat):
13 img = cv2.imread(path)
14 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
15 h, s, v = cv2.split(hsv)
16 s[:,:] = sat
17 hsv = cv2.merge((h,s,v));
18 img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
19 cv2.imwrite('{}_sat{:03d}.jpg'.format(os.path.splitext(path)[0],sat), img)
20
21# 提示ソースの判定用の値
22def get_ratio(path):
23 img = cv2.imread(path)
24
25 b, g, r = cv2.split(img)
26
27 r_g = np.count_nonzero(abs(r - g))
28 r_b = np.count_nonzero(abs(r - b))
29 g_b = np.count_nonzero(abs(g - b))
30 diff_sum = float(r_g + r_b + g_b)
31
32 return diff_sum / img.size # > 0.005
33
34# カラー画像か判定
35# Detect if image is color, grayscale or black and white with Python/PIL
36# https://stackoverflow.com/questions/20068945/detect-if-image-is-color-grayscale-or-black-and-white-with-python-pil
37def detect_color_image(file, MAYBE_COLOR = 100):
38
39 from PIL import Image, ImageStat
40 from functools import reduce
41
42 MONOCHROMATIC_MAX_VARIANCE = 0.005
43 COLOR = 1000
44
45 v = ImageStat.Stat(Image.open(file)).var # =分散
46 is_monochromatic = reduce(lambda x, y: x and y < MONOCHROMATIC_MAX_VARIANCE, v, True)
47 if is_monochromatic:
48 return "Monochromatic image"
49 else:
50 mes = '?'
51 if len(v)==3: # color
52 maxmin = abs(max(v) - min(v))
53 if maxmin > COLOR:
54 mes = "Color"
55 elif maxmin > MAYBE_COLOR:
56 mes = "Maybe color"
57 else:
58 mes = "grayscale"
59
60 return '{}({})'.format(mes, maxmin)
61
62 elif len(v)==1:
63 return "Black and white"
64 else:
65 return "Don't know..."
66
67# テスト画像生成
68to_gray('lena.jpg')
69conv_saturation('lena.jpg',1)
70conv_saturation('lena.jpg',10)
71conv_saturation('lena.jpg',100)
72
73# 各画像を判定
74for path in ['lena.jpg','lena_gray.jpg','lena_sat001.jpg','lena_sat010.jpg','lena_sat100.jpg']:
75 print(path)
76 print(get_ratio(path)) # 提示ソースの判定値
77 print(detect_color_image(path))
78 print()
79
80# 閾値を徐々にあげる
81path = 'lena_sat010.jpg'
82print(path)
83for maybe_color in [100,200,300]:
84 print(detect_color_image(path,maybe_color),maybe_color)