pq_detect.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # -*- coding:utf-8 -*-
  2. from RGB import *
  3. from image_util import *
  4. import os, sys, time
  5. import cv2 as cv
  6. import numpy as np
  7. import random
  8. import math
  9. class PQDetect():
  10. def __init__(self):
  11. self.RGBColor = RGBColor()
  12. def isSnowPic2(self, pic_path):
  13. im1 = cv.imread(pic_path)
  14. h1, w1, c1 = im1.shape
  15. print h1, w1, c1
  16. im1_1 = im1[0:h1 / 2, 0:w1 / 2]
  17. im1_2 = im1[0:h1 / 2, w1 / 2:w1]
  18. im1_3 = im1[h1 / 2:h1, 0:w1 / 2]
  19. im1_4 = im1[h1 / 2:h1, w1 / 2:w1]
  20. hist_list = []
  21. hist_list.append(cv.calcHist([im1_1], [0], None, [256], [0, 256]))
  22. hist_list.append(cv.calcHist([im1_2], [0], None, [256], [0, 256]))
  23. hist_list.append(cv.calcHist([im1_3], [0], None, [256], [0, 256]))
  24. hist_list.append(cv.calcHist([im1_4], [0], None, [256], [0, 256]))
  25. count = 0
  26. totalHist = 0
  27. for hist_1 in hist_list:
  28. for hist_2 in hist_list:
  29. diffHist = cv.compareHist(hist_1, hist_2, cv.HISTCMP_BHATTACHARYYA)
  30. if diffHist <> 0:
  31. count += 1
  32. totalHist += diffHist
  33. four_zone_diff = totalHist / count
  34. print four_zone_diff
  35. rhist = cv.calcHist([im1_1], [0], None, [256], [0, 256])
  36. bhist = cv.calcHist([im1_2], [2], None, [256], [0, 256])
  37. bgr_diff = cv.compareHist(rhist, bhist, cv.HISTCMP_BHATTACHARYYA)
  38. print bgr_diff
  39. if four_zone_diff < 0.1 and bgr_diff < 0.2:
  40. return True
  41. else:
  42. return False
  43. '''
  44. 判断传入的图片,是否为ATV无信号雪花屏。定义雪花屏:清晰度25左右.然后随机取20个区域,查看直方图趋势相似度。
  45. :param pic_path:图片路径
  46. :threshold: 直方图差异临界值。 范围 0 ~ 1
  47. :sharpDiff: 清晰度容错范围值。
  48. :return : True代表是雪花屏,False代表不是雪花屏
  49. '''
  50. def isSnowPic(self, pic_path, threshold=0.1, sharpDiff=10, sharpSnow = 25):
  51. im1 = cv.imread(pic_path)
  52. h1, w1, c1 = im1.shape
  53. sharpP = self.detSharpLaplacian(pic_path)
  54. hist_list = []
  55. for i in range(20):
  56. x1 = random.randint(0,h1/2)
  57. y1 = random.randint(0,w1/2)
  58. rect_h = h1/2
  59. rect_w = w1/2
  60. # print [x1,y1, x1+ rect_w, y1+rect_h]
  61. im = cutMat(im1, [x1,y1, x1+ rect_h, y1+rect_w])
  62. hist = cv.calcHist([im], [0], None, [256], [0, 256])
  63. hist_list.append(hist)
  64. count = 0
  65. totalHist = 0
  66. for hist_1 in hist_list:
  67. for hist_2 in hist_list:
  68. diffHist = cv.compareHist(hist_1, hist_2, cv.HISTCMP_BHATTACHARYYA)
  69. if diffHist <> 0:
  70. count += 1
  71. totalHist += diffHist
  72. four_zone_diff = totalHist / count
  73. print "isSnowPic:", four_zone_diff,sharpP
  74. if four_zone_diff < threshold and abs(sharpP - sharpSnow) <= sharpDiff:
  75. return True
  76. else:
  77. return False
  78. '''
  79. 根据传入的图片路径,计算图片色温
  80. '''
  81. def calculateCCT(self, pic_path):
  82. img = cv.imread(pic_path)
  83. # xyImg = cv.cvtColor(img,cv.COLOR_BGR2XYZ)
  84. xyImg = cv.cvtColor(img, cv.COLOR_RGB2XYZ)
  85. # print "xyImg",xyImg
  86. #色温计算
  87. X = np.average(xyImg[:,:,0])
  88. Y = np.average(xyImg[:,:,1])
  89. Z = np.average(xyImg[:,:,2])
  90. x = X/(X+Y+Z) #色谱XYZ转换成色坐标x
  91. y = Y/(X+Y+Z) #色谱XYZ转换成色坐标y
  92. print "calculateCCT,x,y:",x,y
  93. n = (x-0.3320)/(0.1858-y)
  94. print "calculateCCT,n:",n
  95. # CCT = 437*n**3 + 3601*n**2 + 6831*n + 5517
  96. # CCT = 437*math.pow(n,3) + 3601*math.pow(n,2) + 6831*n + 5517
  97. CCT=-449*math.pow(n,3) + 3525*math.pow(n,2) - 6823.3*n + 5520.33
  98. print "calculateCCT,CCT:",CCT
  99. return CCT
  100. '''
  101. Tenengrad梯度方法利用Sobel算子分别计算水平和垂直方向的梯度,同一场景下梯度值越高,图像越清晰。
  102. 以下是具体实现,这里衡量的指标是经过Sobel算子处理后的图像的平均灰度值,值越大,代表图像越清晰。
  103. :param 图片路径
  104. :return float, 值越大,代表清晰度越高
  105. '''
  106. def detSharpTenengrad(self, pic_path):
  107. img = cv.imread(pic_path)
  108. grayImg = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
  109. sobelImg = cv.Sobel(grayImg, cv.CV_16U, 1, 1)
  110. grayV = cv.mean(sobelImg)[0] # 图像的平均灰度
  111. # cv.putText(img, str(grayV), (20,50), cv.FONT_HERSHEY_COMPLEX, 0.8, (255,255,0))
  112. # cv.imshow("清晰度",img)
  113. # cv.waitKey(0)
  114. return grayV
  115. '''
  116. 采用Laplacian梯度方法检测清晰度
  117. :param 图片路径
  118. :return float, 值越大,代表清晰度越高
  119. '''
  120. def detSharpLaplacian(self, pic_path):
  121. img = cv.imread(pic_path)
  122. return self.detImgSharpLaplacian(img)
  123. def detImgSharpLaplacian(self, img):
  124. grayImg = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
  125. sobelImg = cv.Laplacian(grayImg, cv.CV_16U)[0]
  126. grayV = cv.mean(sobelImg)[0] # 图像的平均灰度
  127. # cv.putText(img, str(grayV), (20, 50), cv.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 0))
  128. # cv.imshow("清晰度", img)
  129. # cv.waitKey(0)
  130. return grayV
  131. '''
  132. 采用方差(Variance)方法检测清晰度。
  133. 方差是概率论中用来考察一组离散数据和其期望(即数据的均值)之间的离散(偏离)成都的度量方法。
  134. 方差较大,表示这一组数据之间的偏差就较大,组内的数据有的较大,有的较小,分布不均衡;
  135. 方差较小,表示这一组数据之间的偏差较小,组内的数据之间分布平均,大小相近。
  136. :param 图片路径
  137. :return float, 值越大,代表清晰度越高
  138. '''
  139. def detSharpVariance(self, pic_path):
  140. img = cv.imread(pic_path)
  141. grayImg = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
  142. # 求灰度图像的标准差
  143. stdValueImg = cv.meanStdDev(grayImg)
  144. # print stdValueImg
  145. meanValue = stdValueImg[1][0][0] # 求得均方差。stdValueImg:(均差array([[ 16.58646894]]), 标准差array([[ 10.1834467]]))
  146. grayV = meanValue * meanValue
  147. # cv.putText(img, str(grayV), (20, 50), cv.FONT_HERSHEY_COMPLEX, 0.8, (255, 255, 0))
  148. # cv.imshow("清晰度", img)
  149. # cv.waitKey(0)
  150. return grayV