# encoding: utf-8 import cv2 as cv import numpy as np import math #裁剪图片 def cutImage(img_addr): img = cv.imread(img_addr) img_arr = np.array(img) hight = img_arr.shape[0] wight = img_arr.shape[1] dest_img = img_arr[hight/2+20:hight,wight/2:wight,:] return dest_img def cmpPicWithRGB(picPath1,picPath2): std_img = cutImage(picPath1) test_img = cutImage(picPath2) width = std_img.shape[0] hight = test_img.shape[1] std_B, std_G, std_R = cv.split(std_img) test_B, test_G, test_R = cv.split(std_img) sum_std_B = 0 sum_std_G = 0 sum_std_R = 0 for x in range(0,width,1): for y in range(0,hight,1): sum_std_B = sum_std_B + std_B[x][y] sum_std_G = sum_std_G + std_G[x][y] sum_std_R = sum_std_R + std_R[x][y] avg_std_B = sum_std_B / (width*hight) avg_std_G = sum_std_G / (width*hight) avg_std_R = sum_std_R / (width*hight) for x in range(0,width,1): for y in range(0,hight,1): if abs(test_B[x][y] - avg_std_B) >10 or abs(test_G[x][y] - avg_std_G) > 10 or abs(test_R[x][y] - avg_std_R[x][y] > 10): print test_B[x][y] print test_G[x][y] print test_R[x][y] print avg_std_B print avg_std_R print avg_std_G return False else: return True class RGBColor(): def __init__(self): pass ''' BGR颜色差值小于offset值时,定性为灰阶色调。 ''' def isGray(self, bgr, offset = 10): # print "RGB isGray:", bgr,abs(bgr[0] - bgr[1]) if abs(bgr[0] - bgr[1]) < offset \ and abs(bgr[1] - bgr[2]) < offset\ and abs(bgr[2] - bgr[0]) < offset: return True else: return False ''' 传入的图片对象,必须是BGR颜色空间。 根据BGR颜色值,判断是否为纯色图片。同时忽略极少的噪点干扰。 :param img:传入的图片对象, BGR颜色空间 :param expTh: 颜色平均值偏差范围,> expTh 则是False。 :return: [判断结果True/False,颜色值] ''' def isSingleColor(self, img, expTh=0.01, splitCount=10): height, width, color = img.shape heightStep = height/splitCount widthStep = width/splitCount totalAvg = self.getAvgBGR(img) expCount = 0.0 for heightCount in range(0,splitCount): for widthCount in range(0, splitCount): height0 = heightStep*heightCount width0 = widthStep*widthCount height1 = height0+heightStep width1 = width0+widthStep scaleAvg = self.getAvgBGR(img[height0:height1, width0:width1]) ret = self.isColorSimilar(totalAvg, scaleAvg, faultTolerance=40) if ret is False: expCount += 1 expRate = expCount/(splitCount*splitCount) print "isSingleColor,expRate:",expRate,expCount if expRate > expTh: return False, totalAvg else: return True, totalAvg def getAvgBGR(self, img): imgB = img[:,:,0] imgG = img[:,:,1] imgR = img[:,:,2] avgB = np.average(imgB) avgG = np.average(imgG) avgR = np.average(imgR) return avgB,avgG,avgR def getMaxBGR(self, img): imgB = img[:, :, 0] imgG = img[:, :, 1] imgR = img[:, :, 2] maxB = np.max(imgB) maxG = np.max(imgG) maxR = np.max(imgR) return maxB, maxG, maxR ''' 判断一张图片是否是纯黑图片。 :param img:需要判断的图片 :param grayTH : 黑色判断的灰阶阈值 :param splitCount: 图片拆分的行列次数 :param expTh:黑色计算的容错区域比例。> expTh 则是False。 ''' def isBlack(self, img, grayTH = 70,splitCount=10, expTh = 0.01): height, width, color = img.shape heightStep = height / splitCount widthStep = width / splitCount totalAvg = self.getAvgBGR(img) expCount = 0.0 for heightCount in range(0, splitCount): for widthCount in range(0, splitCount): height0 = heightStep * heightCount width0 = widthStep * widthCount height1 = height0 + heightStep width1 = width0 + widthStep scaleAvg = self.getAvgBGR(img[height0:height1, width0:width1]) ret = self.isGray(scaleAvg) #print "rgb isBlack,gray ret:", ret if ret is False or scaleAvg[1] > grayTH: expCount += 1 expRate = expCount / (splitCount * splitCount) print "isBlack,expRate:", expRate, expCount if expRate > expTh: return False else: return True ''' # 描述:bgr色差计算。ΔE=( ΔL^2 + ΔA^2 + ΔB^2 ) ^ (1/2) ΔE # 参数:color1、color2: bgr格式 # 返回值: # 相差值,越小越相近。 # 0~50(微小色差),感觉极微; # 50~150(小色差),感觉轻微; # 150~300(较小色差),感觉明显; # 300~600(较大色差),感觉很明显; # 600以上(大色差),感觉强烈。 # ''' def colorDistance(self, color1, color2): b1, g1, r1 = color1 b2, g2, r2 = color2 rmean = (r1 + r2) / 2 R = int(r1) - int(r2) G = int(g1) - int(g2) B = int(b1) - int(b2) return math.sqrt((2 + rmean / 256) * (R ** 2) + 4 * (G ** 2) + (2 + (255 - rmean) / 256) * (B ** 2)) ''' # 描述:颜色是否相近。 # 参数: # color1、color2: bgr格式 # faultTolerance: 容错值大小,表示两颜色的色差值 # 返回值:<= faultTolerance返回True,否则返回False. # # ''' def isColorSimilar(self, color1, color2, faultTolerance=100): if 0: b1 = color1[0] in range(color2[0] - faultTolerance, color2[0] + faultTolerance) b2 = color1[1] in range(color2[1] - faultTolerance, color2[1] + faultTolerance) b3 = color1[2] in range(color2[2] - faultTolerance, color2[2] + faultTolerance) if b1 == True and b2 == True and b3 == True: return True else: return False if 1: val = self.colorDistance(color1, color2) return True if val <= faultTolerance else False