123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- # -*- coding:utf-8 -*-
- import os, sys, time
- from ssat_sdk.device_manage.capturecard_manager import CCardManager
- from pic_tool import ImageCMP
- from sound_tool import AudioIdentify
- from picture.feature_detect import *
- from ssat_sdk.picture.color_space import CIEluvCaculator
- from ssat_sdk.sat_environment import *
- from ocr_convert import OCRConvert
- from ssat_sdk.picture import image_util
- from ssat_sdk.pic_tool import ImageCMP
- import cv2 as cv
- import thread
- import threading
- from ssat_sdk.utils import LoggingUtil
- from ssat_sdk.TvDetect.colorbar_detect import ColorBarDetect
- pyFileName = os.path.split(__file__)[-1]
- def get_current_function_name():
- return inspect.stack()[1][3]
- # 模板匹配全局对象;
- g_threadMonitor = None
- g_monitorResult = {}
- g_stopThread = False
- class TvDetect():
- def __init__(self):
- self.audioChecker = AudioIdentify()
- self.vp = VideoCapture()
- self.featureDetect = FeatureDetect()
- self.CIECaculator = CIEluvCaculator()
- self.OCR = OCRConvert()
- self.className = self.__class__.__name__
- self.imageUtil = image_util.ImageUtil()
- self.imgCMP = ImageCMP()
- self.colorBarDetect = ColorBarDetect()
- '''
- 检测电视锁屏。自行截取电视画面后检索
- :return hasLockStr:是否有锁屏提示字符
- :return isBlack:是否全是黑屏,没有画面
- :return hasLockStr:是否有锁屏提示字符
- '''
- def detectLockScreen(self):
- # lockPic = r"D:\temp-pic\parentlock\channel_lock2.png"
- # lockPic = r"D:\temp-pic\parentlock\channel_lock1.png"
- # lockPic = r"D:\temp-pic\parentlock\source_lock1.png"
- lockPic = os.path.join(getSATTmpDIR(), "lock_screen.png")
- self.vp.takePicture(lockPic)
- return self.detectLockPic(lockPic)
- '''
- 检测电视锁屏.根据提供的图片进行检测
- :param lockPic:电视画面的图片路径
- :return hasLockStr:是否有锁屏提示字符
- :return isBlack:是否全是黑屏,没有画面
- :return hasLockStr:是否有锁屏提示字符
- '''
- def detectLockPic(self, lockPic):
- maxDiff = 5
- blackLuv = (11,96,136)
- hasLockStr = False
- isBlack = True
- lockRect = self.featureDetect.findRectByFile(lockPic, "parentLock")
- print lockRect
- rectPic = os.path.join(getSATTmpDIR(), "rect.png")
- image_util.saveCropPic(lockPic, rectPic, lockRect)
- info = self.OCR.getStr(rectPic, "english", 2)
- print "detectLockPic,str:",info
- if info.lower().find("locked") > 0:
- hasLockStr = True
- retImgList = image_util.saveRetCropPic(lockPic, lockRect)
- for index in range(retImgList.__len__()):
- # cv.imshow(str(index),retImgList[index])
- imgLuv = cv.cvtColor(retImgList[index], cv.COLOR_BGR2Luv)
- l, u, v = self.CIECaculator.getAverageLUV(imgLuv)
- diffLevel = self.CIECaculator.getDiffuvLevel(blackLuv, (l, u, v))
- if (diffLevel > maxDiff):
- isBlack = False
- # cv.waitKey(0)
- # cv.destroyAllWindows()
- # print hasLockStr, isBlack, lockPic
- return hasLockStr, isBlack, lockPic
- '''
- 传入电视的重现率检测画面(22293/4 pattern304 或者TG39 mark画面),按像素计算重现率。
- :param pic_path:重现率电视画面图片路径
- :param scaleGray:刻度与悲剧G枪分界值
- :param scaleMax_W:宽,即水平刻度数,不包含图像边界
- :param scaleMax_H:高,即垂直刻度数,不包含图像边界
- :param scaleUnit_W:宽,水平刻度单位值
- :param scaleUnit_H: 高,垂直刻度单位值
- :param scaleLineOffset:刻度线段可偏离像素点数
- :return 浮点数组。[左边重显率,右边重显率,上边重显率,下边重显率]
- '''
- def detectOverScan(self, pic_path, scaleMax_W=10, scaleMax_H=10, scaleUnit_W=0.02, scaleUnit_H=0.04, scaleLineOffset=3):
- img = cv.imread(pic_path)
- img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
- h1, w1 = img_gray.shape
- center_height, center_width = self.findCenterPoint(img_gray)
- #计算左边重现率
- # print "detectOverScan,scale_left"
- scale_left = self.detectWhiteScale(img_gray, scaleMax_W, scaleUnit_W,
- (0, center_height-scaleLineOffset),
- (center_width/3, center_height-scaleLineOffset))
- # print "detectOverScan,scale_right"
- scale_right = self.detectWhiteScale(img_gray, scaleMax_W, scaleUnit_W,
- (w1-1, center_height-scaleLineOffset),
- (5*center_width/3, center_height-scaleLineOffset))
- # print "detectOverScan,scale_up"
- scale_up = self.detectWhiteScale(img_gray, scaleMax_H, scaleUnit_H,
- (center_width-scaleLineOffset, 0),
- (center_width-scaleLineOffset, center_height/2))
- # print "detectOverScan,scale_down"
- scale_down = self.detectWhiteScale(img_gray, scaleMax_H, scaleUnit_H,
- (center_width - scaleLineOffset, h1-1),
- (center_width - scaleLineOffset, 3*center_height / 2))
- # print scale_left,scale_right,scale_up,scale_down
- return scale_left,scale_right,scale_up,scale_down
- '''
- 寻找图片白色条相交中心点,例如:重现率图片
- '''
- def findCenterPoint(self, img):
- h1,w1 = img.shape
- center_x1 = 4 * w1 / 10
- center_y1 = 4 * h1 / 10
- center_x2 = 6 * w1 / 10
- center_y2 = 6 * h1 / 10
- # print center_x1, center_y1, center_x2, center_y2
- area_center = [center_x1, center_y1, center_x2, center_y2]
- img_center = image_util.cutMat(img, area_center)
- h2, w2 = img_center.shape
- # print h2,w2,dim2
- # 寻找中心点的高坐标
- line_w = w2 / 20
- line_1 = [line_w, h2 / 3, line_w, 2 * h2 / 3]
- # print "line_1:",line_1
- center_height = center_y1
- grayAvg1 = self.imageUtil.calGrayAvg(img_center, line_1)
- # print "grayAvg:",grayAvg1
- for height in range(line_1[1], line_1[3]):
- if img_center[height, line_w] >= grayAvg1:
- center_height += height
- break
- print "center_height:",center_height
- # 寻找纵向直线的宽坐标
- line_h = h2 / 20
- line_2 = [w2 / 3, line_h, 2 * w2 / 3, line_h]
- center_width = center_x1
- grayAvg2 = (np.max(line_1) + np.min(line_1)) / 2
- for width in range(line_2[0], line_2[2]):
- if img_center[line_h, width] >= grayAvg2:
- center_width += width
- break
- print "center_width:", center_width
- return center_height, center_width
- '''
- 判断是否在重显率画面
- :param picPath:图片路径
- :return True/False:True:是重显率画面,False:不是重显率
- '''
- def isOverScan(self, picPath):
- print "isOverScan,picPath:",picPath
- srcImg = cv.imread(picPath)
- height,widht,dim = srcImg.shape
- grayImg = cv.cvtColor(srcImg,cv.COLOR_BGR2GRAY)
- center_height, center_width = self.findCenterPoint(grayImg)
- dHeight = center_height*2.0/height
- dWidth = center_width*2.0/widht
- if 0.98 < dHeight < 1.02 and 0.98 < dWidth < 1.02:
- return True
- else:
- return False
- '''
- 根据指定的直线,扫描刻度线条。去掉刻度线条宽度的影响,同时刻度线条和背景灰阶阈值,采用像素点平均值。
- :param img:待检测图片。22293 pattern
- :param scaleLevel:刻度等级数,即多少条刻度线.刻度线不包含图像边界线。
- :param scaleUnit: 每一个刻度,读数值
- :param pointStart:刻度起始点坐标。 width-x,height-y坐标系
- :param pointEnd: 刻度重点坐标。 width-x,height-y坐标系
- :return 重显率scaleDG:取值范围 0.00 ~ 1.00
- '''
- def detectWhiteScale(self, img, scaleLevel, scaleUnit, pointStart, pointEnd, grayMidOffset = 50):
- grayMid = self.imageUtil.calGrayAvg(img, (pointStart[0],pointStart[1], pointEnd[0],pointEnd[1])) + grayMidOffset
- print "detectWhiteScale:pointStart:pointEnd:grayMid:",(pointStart,pointEnd, grayMid)
- scalePointList = []
- w_list,h_list = self.genPointHWArray(pointStart,pointEnd)
- selPoint = None
- prevPoint = (w_list[0], h_list[0])
- for height in h_list:
- for width in w_list:
- # print img[prevPoint[1], prevPoint[0]] , img[height,width]
- if img[height,width] > grayMid:
- if selPoint is None or \
- (int(img[prevPoint[1], prevPoint[0]]) <= grayMid
- and image_util.caculateLinLen((selPoint[0],selPoint[1],width,height)) > 5):
- # 每条刻度的宽度像素点不定,取刻度的第一个像素点,作为刻度坐标
- selPoint = (width,height)
- scalePointList.append(selPoint)
- prevPoint = (width,height)
- print u"刻度点列表:", scalePointList
- if scalePointList.__len__() < 2:
- print u"重显率检测失败,刻度点列表:", scalePointList
- return -1.0
- x1,y1 = scalePointList[0]
- x2,y2 = scalePointList[1]
- step = image_util.caculateLinLen((x1,y1, x2,y2))
- # print "detectWhiteScale step:", step
- hintLevel = scaleLevel - scalePointList.__len__()
- # print "detectWhiteScale hintLevel:",hintLevel
- # direction = self.featureDetect.lineUtil.lineDirect((x1,y1, x2,y2))
- oneLevel = (step - (image_util.caculateLinLen((x1,y1,pointStart[0],pointStart[1]))))/step
- # print "detectWhiteScale oneLevel:",oneLevel
- scaleDG = 1 - (hintLevel*scaleUnit + oneLevel*scaleUnit)
- # print "detectWhiteScale scaleDG:",scaleDG
- return scaleDG
- '''
- 将坐标全部存入数组,解决坐标从小到大和从大到小均可遍历问题。
- '''
- def genPointHWArray(self, pointStart, pointEnd):
- w1 = pointStart[0]
- h1 = pointStart[1]
- w2 = pointEnd[0]
- h2 = pointEnd[1]
- w_list = []
- h_list = []
- if w1 >= w2:
- for dw in range(0, w1-w2+1):
- w_list.append(w1-dw)
- else:
- for w in range(w1, w2+1):
- w_list.append(w)
- if h1 >= h2:
- for dh in range(0, h1-h2+1):
- h_list.append(h1-dh)
- else:
- for h in range(h1, h2+1):
- h_list.append(h)
- # print "w_list:",w_list
- # print "h_list:",h_list
- return w_list,h_list
- '''
- 监听视频,查看是否会中途无声无像
- :param 要监听时间长度。单位秒。
- :param 要监听的画面,标准:0 代表黑屏,1 代表有画面
- :param galleryDir.指定窗口样图路径,有代表需要监听,没有代表不需要监听
- :param blackTh: 黑色图片判断阈值,低于或等于则表示为黑色。默认50
- :return 两个数组:SoundExpList,VideoExpList。 list的格式:数组内存放字典。字典{"time":time.asctime( time.localtime(time.time()))}。
- List里面的第一个time值,表示开始监听的时间。
- SoundExpList第一个字典数据,有audio 键,取录音文件路径。status键:0 代表无异常;1代表没有声音发出;2代表声音有间断。
- VideoExpList每一个异常字典数据,有picture键,取图片。第一个字典数据中,status键:0 代表一直有画面;1代表一直黑屏;2代表有黑屏出现,-1代表截图失败。
- 第一个字典数据中,motion_picture:1 代表运动画面,0 代表静态画面。
- '''
- def monitorVideo(self, seconds = 10, galleryDir = "", picTarget=1, blackTh = 50):
- soundExpList = []
- soundTID = thread.start_new_thread(self.audioChecker.monitorSound, (seconds, soundExpList))
- pictureExpList = []
- picTID = thread.start_new_thread(self.monitorTvPicture, (seconds,pictureExpList, picTarget, blackTh))
- global g_monitorResult
- if os.path.exists(unicode(galleryDir)) == True:
- self.startMonitorAbnormal(seconds, galleryDir)
- count = 0
- while soundExpList.__len__() < 1 or pictureExpList.__len__() < 1:
- print "monitorVideo ...seconds:",count
- time.sleep(1)
- count += 1
- # print "monitorVideo, abnormal:",g_monitorResult
- # 为保持向前兼容,g_monitorResult结果单独使用getMonitorAbnormalResults获取
- return soundExpList,pictureExpList#,g_monitorResult
- def monitorTvPicture(self,seconds, expList, picTarget=1, blackTh = 50):
- hasImage = False
- startSeconds = time.time()
- expList.append({"time": time.asctime(time.localtime(startSeconds)),"picture":"", "status":0})
- expList[0]["motion_picture"] = 0 #默认为静态画面
- curSeconds = time.time()
- prevPic = os.path.join(getSATTmpDIR(), "monitorTvPicture" + str(time.time()) + ".png")
- self.vp.takePicture(prevPic)
- LoggingUtil.printLog("Record picture...")
- while (curSeconds - startSeconds) < seconds:
- currentPic = os.path.join(getSATTmpDIR(), "monitorTvPicture"+str(time.time())+".png")
- self.vp.takePicture(currentPic)
- # 加0.5秒延时,防止截图过快导致异常
- time.sleep(0.5)
- curSeconds = time.time()
- try:
- #检测画面是否纯黑色背景
- if picTarget == 1:#黑屏无画面,异常
- if (self.imgCMP.isBlack(currentPic)):
- expList.append({"time":time.asctime(time.localtime(curSeconds)),"picture":currentPic})
- else:
- hasImage = True
- else: #黑屏无画面,正常
- if (self.imgCMP.isBlack(currentPic, blackTh)):
- pass
- else:
- expList.append({"time":time.asctime(time.localtime(curSeconds)),"picture":currentPic})
- hasImage = True
- except Exception,e:
- # 未能正常截到图,导致测试失败
- LoggingUtil.printLog(u"monitorTvPicture截图失败!!!\nErrorMsg:%s\ncurrentPic路径:%s\n"%(e,currentPic))
- expList[0]["status"] = -1
- return
- #检测画面是动态还是静态
- if self.imgCMP.cmpPicTotal(prevPic, currentPic, expDotRate=0) is False:
- expList[0]["motion_picture"] = 1
- prevPic = currentPic
- LoggingUtil.printLog("Record picture End")
- if hasImage and expList.__len__() == 1:
- expList[0]["status"] = 0
- elif hasImage and expList.__len__() > 1:
- expList[0]["status"] = 2
- else:
- expList[0]["status"] = 1
- '''
- # 描述:监控异常
- # 参数:
- # seconds:监控时长.
- # galleryDir:图库目录路径
- # 返回:bool, fileAbnormal, coordinate,fileTV
- # True:有异常,False:正常
- # fileAbnormal:异常时,与异常匹配的图库文件路径
- # coordinate:异常时,异常框的坐标。
- # fileTV:出现异常的视频截图路径。
- # '''
- def monitorAbnormal(self, seconds, galleryDir):
- pic_path = ""
- result = {"result": False, "tmpVal":0, "galleryFile":"", "coordinate":[0,0,0,0]}
- setting = {'method':5, 'colorType':0, 'thresholdVal':0, 'thresholdMaxVal':255} #可从配置文件读取,不用从参数传入
- global g_stopThread
- startSeconds = time.time()
- while g_stopThread == False:
- # 一秒截一图;
- pic_path = os.path.join(getAbnormalDir(), time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))+".png")
- self.vp.takePicture(pic_path)
- # 异常匹配;
- result = self.featureDetect.matchImage(pic_path, None, galleryDir, setting)
- if result["result"] == True:
- result["screenFile"] = pic_path
- break
- # 删除无异常的截图;
- os.remove(pic_path)
- # 超时退出线程;
- if int(time.time() - startSeconds) > seconds:
- break
- # 返回全局对象;
- if result["result"] == False:
- result["screenFile"] = ""
- global g_monitorResult
- g_monitorResult = result
- print u'异常监控结果:',g_monitorResult["result"],g_monitorResult["tmpVal"],g_monitorResult["coordinate"],g_monitorResult["screenFile"].encode('gb2312'),g_monitorResult["galleryFile"].encode('gb2312')
- # 启动监控线程;
- def startMonitorAbnormal(self, seconds, galleryDir):
- global g_threadMonitor,g_stopThread
- if g_threadMonitor is not None and g_threadMonitor.is_alive() == True:
- print u'线程已运行'
- return
- g_stopThread = False
- g_threadMonitor = threading.Thread(target=self.monitorAbnormal, name='MonitorAbnormal', args=(seconds,galleryDir))
- g_threadMonitor.start()
- # 停止监控;
- def stopMonitorAbnormal(self):
- global g_threadMonitor,g_stopThread
- if g_threadMonitor is not None and g_threadMonitor.is_alive() == True:
- g_stopThread = True
- print u'开始停止'
- else:
- print u'线程已停止'
- '''
- # 描述:获取监控结果
- #
- # '''
- def getMonitorAbnormalResults(self):
- global g_monitorResult
- return g_monitorResult
- '''
- HDMI重显率测试:1080P及以上分辨率重显率为100%;1080P分辨率以下重显率为95%-97%,显示器模式时为100%.
- 片源 22294: pattern:304
- 根据传入的图片和重显率要求,返回检测结果。
- 重现率最小界限,增加0.01容错。两边偏移不超过0.02
- :param picPath: 电视截图路径
- :param resolution: "Full":全屏显示。 "HD":高清, "SD":标清
- :param offsetMax = 0.02#中心点偏移的容错值
- :param downTh = 0.01#重现率偏小的容错值
- :return :两个参数。参数1 True或者False,参数2, 具体结果参数数组。
- '''
- def detectHDMIOverScan(self, picPath, resolution="", STD=[],offsetMax = 0.02, downTh = 0):
- print "detectHDMIOverScan:", picPath, resolution
- if STD == []:
- hdmiRSTD = {"full":[1.0,1.0], "hd":[1.0,1.0], "sd":[0.95,0.97]}
- STD = hdmiRSTD[resolution.lower()]
- left, right, up, down = self.detectOverScan(picPath)
- # print "detectHDMIOverScan,left, right, up, down:", left, right, up, down
- hOverscan, hOffset = self.calOverScan(left,right)
- vOverscan, vOffset = self.calOverScan(up,down)
- if hOverscan + downTh >= STD[0] and hOverscan <= STD[1] and hOffset < offsetMax\
- and (vOverscan + downTh) >= STD[0] and vOverscan <= STD[1] and vOffset < offsetMax:
- return True, [resolution, STD, [(hOverscan,hOffset), (vOverscan,vOffset)]]
- else:
- return False, [resolution, STD, [(hOverscan,hOffset), (vOverscan,vOffset)]]
- def calOverScan(self, side1, side2):
- scale = (side1+side2)/2
- return round(scale, 3), round(abs(side1-side2),3)
- '''
- AV重显率测试:重显率为95%-97%
- 片源 22294: pattern:304
- 重现率最小界限,增加0.01容错。两边偏移不超过0.02
- 根据传入的图片和重显率要求,返回检测结果。
- :param picPath: 电视截图路径
- :param offsetMax = 0.02#中心点偏移的容错值
- :param downTh = 0.01#重现率偏小的容错值
- :return :两个参数。参数1 True或者False,参数2, 具体结果参数数组。
- '''
- def detectAVOverScan(self, picPath, STD = [0.95,0.97], offsetMax = 0.02, downTh = 0):
- print "detectAVOverScan:", picPath
- left, right, up, down = self.detectOverScan(picPath)
- # print "detectAVOverScan,left, right, up, down:", left, right, up, down
- hOverscan, hOffset = self.calOverScan(left,right)
- vOverscan, vOffset = self.calOverScan(up,down)
- if hOverscan+downTh >= STD[0] and vOverscan <= STD[1] and hOffset < offsetMax\
- and hOverscan+downTh >= STD[0] and vOverscan <= STD[1] and vOffset < offsetMax:
- return True, [STD, [(hOverscan, hOffset), (vOverscan, vOffset)]]
- else:
- return False, [STD, [(hOverscan, hOffset), (vOverscan, vOffset)]]
- '''
- ATV重显率(重现率要求95%-97%之间,(行6.5-7,帧5-6)
- 片源 检测片源TG39 mark
- 根据传入的图片和重显率要求,返回检测结果。
- 重现率最小界限,增加0.01容错。两边偏移不超过0.02
- :param picPath: 电视截图路径
- :param offsetMax = 0.02#中心点偏移的容错值
- :param downTh = 0.01#重现率偏小的容错值
- :return :两个参数。参数1 True或者False,参数2, 具体结果参数数组。
- '''
- def detectAtvOverScan(self, picPath, STD = [0.95, 0.97], offsetMax = 0.02, downTh = 0):
- print "detectAtvOverScan:", picPath
- left, right, up, down = self.detectOverScan(picPath, scaleMax_W=4, scaleMax_H=5, scaleUnit_W=0.05, scaleUnit_H=0.05, scaleLineOffset=5)
- # print "detectAtvOverScan,left, right, up, down:", left, right, up, down
- hOverscan, hOffset = self.calOverScan(left,right)
- vOverscan, vOffset = self.calOverScan(up,down)
- if (hOverscan + downTh) >= STD[0] and hOverscan <= STD[1] and hOffset < offsetMax \
- and (vOverscan + downTh) >= STD[0] and vOverscan <= STD[1] and vOffset < offsetMax:
- return True, [STD, [(hOverscan, hOffset), (vOverscan, vOffset)]]
- else:
- return False, [STD, [(hOverscan, hOffset), (vOverscan, vOffset)]]
- def detectAtv3116OverScan(self, picPath, STD = [0.95, 0.97], offsetMax = 0.02, downTh = 0):
- print "detectAtv3116OverScan:", picPath
- left, right, up, down = self.detectOverScan(picPath, scaleMax_W=4, scaleMax_H=3, scaleUnit_W=0.05,
- scaleUnit_H=0.05, scaleLineOffset=5)
- # print "detectAtvOverScan,left, right, up, down:", left, right, up, down
- hOverscan, hOffset = self.calOverScan(left, right)
- vOverscan, vOffset = self.calOverScan(up, down)
- if (hOverscan + downTh) >= STD[0] and hOverscan <= STD[1] and hOffset < offsetMax \
- and (vOverscan + downTh) >= STD[0] and vOverscan <= STD[1] and vOffset < offsetMax:
- return True, [STD, [(hOverscan, hOffset), (vOverscan, vOffset)]]
- else:
- return False, [STD, [(hOverscan, hOffset), (vOverscan, vOffset)]]
- '''
- 假定重现率正确
- 检测画面:TG39 网格
- 根据传入的网格图片,判断比例模式是否正确。
- :param mode: "full", origin, smart, zoom
- :param testPic: 图片路径
- :return :1个参数。参数1 True或者False
- '''
- def detectATVAspectRatio(self, testPic, mode):
- scale_W = 17.0
- scale_H = 13.0
- widthRatio = 0
- heightRatio = 0
- if mode == "full":
- widthRatio = 1.0
- heightRatio = 1.0
- elif mode == "origin":
- widthRatio = 1.0
- heightRatio = 0
- elif mode == "smart":
- widthRatio = 1.0
- heightRatio = 11/scale_H
- elif mode == "zoom":
- widthRatio = 1.0
- heightRatio= 9/scale_H
- else:
- pass
- return self.detectAspectRatio(testPic, scale_W, scale_H,widthRatio,heightRatio)
- '''
- 假定重现率正确
- 检测画面:22294 Timing65 Pattern55
- 根据传入的网格图片,判断比例模式是否正确。
- :param mode: "full", origin, smart, zoom
- :param testPic: 图片路径
- :return :1个参数。参数1 True或者False
- '''
- def detectHDMIAspectRatio(self, testPic, mode):
- scale_W = 15.0
- scale_H = 11.0
- widthRatio = 0
- heightRatio = 0
- if mode == "full":
- widthRatio = 1.0
- heightRatio = 1.0
- elif mode == "origin":
- widthRatio = 1.0
- heightRatio = 0
- elif mode == "smart":
- widthRatio = 1.0
- heightRatio = 11 / scale_H
- elif mode == "zoom":
- widthRatio = 1.0
- heightRatio = 9 / scale_H
- else:
- pass
- return self.detectAspectRatio(testPic, scale_W, scale_H,widthRatio,heightRatio)
- '''
- 假定重显率正确
- 检测画面:22294 Timing36 Pattern55
- 根据传入的网格图片,判断比例模式是否正确。
- :param mode: "full", origin, smart, zoom
- :param testPic: 图片路径
- :return :1个参数。参数1 True或者False
- '''
- def detectAVAspectRatio(self, testPic, mode):
- return self.detectHDMIAspectRatio(testPic,mode)
- '''
- 根据传入的网格图片,判断比例模式是否正确。
- :param mode: "full", origin, smart, zoom
- :param testPic: 图片路径
- :param scale_W:水平宽的网格线数量
- :param scale_H:垂直高的网格线数量
- :param widthRatio:相比于origin,水平宽的比例要求
- :param heightRatio:相比于origin,垂直高的比例要求
- :param scaleGray:网格黑色背景和白色刻度线的G枪分界线
- :return :1个参数。参数1 True或者False
- '''
- def detectAspectRatio(self, testPic, scale_W, scale_H, widthRatio, heightRatio,scaleGray=80):
- print "detectAspectRatio:", scale_W, scale_H
- img = cv.imread(testPic)
- height, width, color =img.shape
- scalePointListW = self.getScaleNumber(img, (0,5), (width-1, 5), scaleGray)
- print "detectAspectRatio,scalePointListW:",scalePointListW.__len__(),scalePointListW
- scalePointListH = self.getScaleNumber(img, (5,0), (5, height-1), scaleGray)
- print "detectAspectRatio,scalePointListH:",scalePointListH.__len__(),scalePointListH
- # print "detectAspectRatio:",scalePointListW.__len__() /scale_W,widthRatio,scalePointListH.__len__() / scale_H,heightRatio
- if scalePointListW.__len__() /scale_W == widthRatio\
- and scalePointListH.__len__() / scale_H == heightRatio:
- return True
- else:
- return False
- def getScaleNumber(self, img,pointStart,pointEnd, scaleGray):
- # print "getScaleNumber:", pointStart, pointEnd
- scalePointList = []
- w_list, h_list = self.genPointHWArray(pointStart, pointEnd)
- selPoint = None
- prevPoint = (w_list[0], h_list[0])
- for height in h_list:
- for width in w_list:
- # print img[prevPoint[1], prevPoint[0]][1] , img[height,width][1],prevPoint[1], prevPoint[0]
- if img[height, width][1] > scaleGray:
- if selPoint is None or \
- int(img[prevPoint[1], prevPoint[0]][1]) <= scaleGray:
- # 每条刻度的宽度像素点不定,取刻度的第一个像素点,作为刻度坐标
- selPoint = (width, height)
- scalePointList.append(selPoint)
- prevPoint = (width, height)
- return scalePointList
- '''
- 检测电视是否已经关机
- 检测方式:1 检测画面是否有变化;检测连续5张截图,均没有变化,且四个角落为相同纯色,且没有声音,则表示处于关机状态。
- 声音检测和纯色检测,可选。
- :param : checkSignle:选择是否要检测四周纯色。
- :param :checkAudio : 是否要检测无声。
- :param : colorOffset : 颜色允许的偏移量
- :param : expDotRate : 异常点比例范围上限.前后两张图片差分时的差异点比例。
- :return : [检测结果,[图片地址列表], [音频地址列表]]
- '''
- def detectPowerOff(self, checkSignle=True, checkAudio=True, colorOffset=20, expDotRate = 0.0001):
- picList = []
- soundList = []
- ccard= CCardManager()
- count = 0
- matchCount = 0
- previewPic = os.path.join(getSATTmpDIR(), "detectPowerOff_"+str(time.time())+".png")
- ccard.takePicture(previewPic)
- picList.append(previewPic)
- while count < 5:
- currentPic = os.path.join(getSATTmpDIR(), "detectPowerOff_"+str(time.time())+".png")
- ret = ccard.takePicture(currentPic)
- print "detectPowerOff,截图:",ret
- if ret == 1:
- count += 1
- ret1 = self.imgCMP.cmpPicTotal(previewPic, currentPic, colorOffset, expDotRate)
- print "detectPowerOff,前后图片比对:",ret1
- #检测4个角落纯色
- if checkSignle is True:
- ret2 = self.imgCMP.checkAroundSSColor(currentPic)
- print "detectPowerOff,四周相同纯色:", ret2
- else:
- ret2= True
- if ret1 and ret2:
- matchCount += 1
- previewPic = currentPic
- picList.append(currentPic)
- if matchCount < 5:
- return False, picList, soundList
- #检测声音
- if checkAudio is True:
- self.audioChecker.startCHK(5)
- soundList.append(self.audioChecker.audioFile)
- return not self.audioChecker.isOK(), picList, soundList
- else:
- return True, picList, soundList
- def isColorBar(self, picPath, type):
- if type.lower()=="hdmi" or type.lower()=="dtv":
- return self.colorBarDetect.isHDMIColorBar(picPath)
- elif type.lower()=="av":
- return self.colorBarDetect.isAVColorBar(picPath)
- elif type.lower()=="atv":
- return self.colorBarDetect.isATVColorBar(picPath)
- else:
- return False
- if __name__ == "__main__":
- tvDetect = TvDetect()
- # pic = "D:/test/4k2.jpg"
- pic = "D:/test/colorbar_hdmi_std.png"
- ret = tvDetect.isColorBar(pic,"hdmi")
- print "isColorBar HDMI:",ret
- ret = tvDetect.isColorBar(pic,"dtv")
- print "isColorBar DTV:",ret
- ret = tvDetect.isColorBar(pic,"av")
- print "isColorBar AV:",ret
- ret = tvDetect.isColorBar(pic,"atv")
- print "isColorBar ATV:",ret
- # print "detectHDMIOverScan:", tvDetect.detectHDMIOverScan(pic,"full")
- # lockPic = r"D:\temp-pic\parentlock\unlockChannel_channelLock.jpg"
- # lockPic = r"D:\temp-pic\parentlock\unlockTV_image.jpg"
- # lockPic = r"D:\temp-pic\parentlock\inputLock_image.jpg"
- # print tvDetect.detectLockPic(lockPic)
- # print tvDetect.monitorVideo(500)
- # time.sleep(2)
- # print tvDetect.startMonitorAbnormal(1000, r'C:\Users\jianfeng1.wang\Pictures\图库')
- # print tvDetect.startMonitorAbnormal(10, r'C:\Users\jianfeng1.wang\Pictures\图库')
- # time.sleep(10)
- # tvDetect.stopMonitorAbnormal()
- # time.sleep(11)
- # print tvDetect.startMonitorAbnormal(10, r'C:\Users\jianfeng1.wang\Pictures\图库')
|