本文轉自https://www.cnblogs.com/zwq-zju/p/9721613.html
基本原理
灰度圖分兩種情況:
單通道的圖片
RGB 三通道的圖片,但是每個通道的值相等
對于單通道的圖片只需要判斷圖片的通道值是否為1
對于RGB模式的圖片,情況稍稍復雜些迹卢。理論上只需判斷RGB三個通道的值是否相等,但是現(xiàn)實中灰度圖常常各通道間存在輕微差異徒仓,但是人眼難以察覺腐碱,依舊可以認為是灰度圖。所以現(xiàn)實中掉弛,應該判斷三個通道間的差異大小比較合理症见。
這里采取的策略是計算三個通道間像素值的差的方差的均值,小于一定閾值的就判斷為灰度圖殃饿。
實現(xiàn)
下面用python做個示例:
只需要用到 PIL 和 numpy
代碼:
import numpy as np
from PIL import Image
# 黑白照片(灰度圖)識別
def isGrayMap(img, threshold = 15):
"""
入?yún)ⅲ? img:PIL讀入的圖像
threshold:判斷閾值谋作,圖片3個通道間差的方差均值小于閾值則判斷為灰度圖。
閾值設置的越小乎芳,容忍出現(xiàn)彩色面積越凶裱痢;設置的越大奈惑,那么就可以容忍出現(xiàn)一定面積的彩色吭净,例如微博截圖。
如果閾值設置的過小肴甸,某些灰度圖片會被漏檢寂殉,這是因為某些黑白照片存在偏色,例如發(fā)黃的黑白老照片原在、
噪聲干擾導致灰度圖不同通道間值出現(xiàn)偏差(理論上真正的灰度圖是RGB三個通道的值完全相等或者只有一個通道友扰,
然而實際上各通道間像素值略微有偏差看起來仍是灰度圖)
出參:
bool值
if len(img.getbands()) == 1:
return True
img1 = np.asarray(img.getchannel(channel=0), dtype=np.int16)
img2 = np.asarray(img.getchannel(channel=1), dtype=np.int16)
img3 = np.asarray(img.getchannel(channel=2), dtype=np.int16)
diff1 = (img1 - img2).var()
diff2 = (img2 - img3).var()
diff3 = (img3 - img1).var()
diff_sum = (diff1 + diff2 + diff3) / 3.0
if diff_sum <= threshold:
return True
else:
return False
img = Image.open(path)
res = isGrayMap(img)