| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 | # -*- coding:utf-8 -*-import os, sys, timeimport inspectimport cv2 as cvimport numpy as npfrom ssat_sdk.utils import LoggingUtilpyFileName = os.path.split(__file__)[-1]def get_current_function_name():    return inspect.stack()[1][3]'''按照坐标系调整区域数值:param areaRXDY:二维区域。坐标系:x轴:水平向右,y轴:纵向向下:return areaDXRY:二维区域。坐标系:x轴:纵向向下,y轴:水平向右'''def coordinateRXDY2DXRY(areaRXDY):    areaDXRY = []    areaDXRY.append(areaRXDY[1])    areaDXRY.append(areaRXDY[0])    areaDXRY.append(areaRXDY[3])    areaDXRY.append(areaRXDY[2])    return areaDXRY'''截取图片区域。:param area:二维区域。area按照常规x,y坐标描述。示例:[x1,y1,x2,y2]. 点(x1,y1)为矩形左上角,点(x2,y2)为矩形右下角。'''def cutMat(srcimg, area):    try:        mat_area = coordinateRXDY2DXRY(area)        # print "cutMat:mat_area:", mat_area        imgArr = np.array(srcimg)        retMat = imgArr[int(mat_area[0]):int(mat_area[2]),int(mat_area[1]):int(mat_area[3])]        del imgArr        return retMat    except Exception, e:        LoggingUtil.getDebugLogger().info(pyFileName, "image_util", get_current_function_name(), 'ERROR:截图异常:'+str(e))        return None'''    # 描述:裁剪图片,返回指定裁剪区域的图片;    # 参数:    #   srcimg:opencv.imread打开的对象。    #   area: 要裁剪的区域,示例:[x1,y1,x2,y2]. 点(x1,y1)为矩形左上角,点(x2,y2)为矩形右下角。    #    # 返回:成功返回裁剪区域的图片对象,否则返回None    #    # 注意:相对cutMat来说,少一步坐标转换。    # '''def cutImage(srcimg, area):    try:        return np.array(srcimg[area[1]:area[3]+1, area[0]:area[2]+1])    except Exception,e:        LoggingUtil.getDebugLogger().info(pyFileName, "image_util", get_current_function_name(), 'ERROR:裁剪图片异常:'+str(e))        return None'''    # 描述:裁剪图片,返回指定裁剪区域的图片;    # 参数:    #   imgPath:图片路径    #   area: 要裁剪的区域,示例:[x1,y1,x2,y2]. 点(x1,y1)为矩形左上角,点(x2,y2)为矩形右下角。    #    # 返回:成功返回裁剪区域的图片对象,否则返回None    #    # 注意:相对cutMat来说,少一步坐标转换。    # '''def cutImageByPath(imgPath, area):    srcimg = cv.imread(imgPath)    try:        dstImg = cutImage(srcimg, area)        del srcimg        return dstImg    except Exception,e:        LoggingUtil.getDebugLogger().info(pyFileName, "image_util", get_current_function_name(), 'ERROR:裁剪图片异常:'+str(e))        return Nonedef saveCropImg(srcImg, destPic, area):    if srcImg is None:        LoggingUtil.getDebugLogger().info(pyFileName, "image_util", get_current_function_name(), 'SDK:打开图像返回空对象,文件可能不存在或无权限打开')        return False    if len(area) != 4:        LoggingUtil.getDebugLogger().info(pyFileName, "image_util", get_current_function_name(), 'SDK:给定的区域坐标无效:'+str(area))        return False    destImg = cutMat(srcImg, area)    if destImg is None:        LoggingUtil.getDebugLogger().info(pyFileName, "image_util", get_current_function_name(), 'SDK:截图失败:')        return False    cv.imwrite(destPic,destImg)    del destImg    return Truedef saveCropPic(srcPic, destPic, area):    srcImg = cv.imread(srcPic)    ret = saveCropImg(srcImg, destPic, area)    del srcImg    return retdef cutImgWithRate(srcImg, destPic, rateArea):    height, width, dim = srcImg.shape    print "srcImg: height, width:", height, width, rateArea    dest_x1 = int(width * rateArea[0])    dest_x2 = int(width * rateArea[2])    dest_y1 = int(height * rateArea[1])    dest_y2 = int(height * rateArea[3])    print "dest: dest_x1,dest_y1, dest_x2, dest_y2:", dest_x1,dest_y1, dest_x2, dest_y2    destImg = cutMat(srcImg, (dest_x1,dest_y1, dest_x2, dest_y2))    cv.imwrite(destPic, destImg)    del destImg'''根据比例裁剪图片,并保存裁剪结果到指定文件中'''def cutPicWithRate(srcPic, destPic, rateArea):    srcImg = cv.imread(srcPic)    cutImgWithRate(srcImg, destPic, rateArea)    del srcImg'''截取选中区域以外的图片'''def saveRetCropPic(srcPic, area):    srcImg = cv.imread(srcPic)    imgList = saveRetCropImg(srcImg, area)    del srcImg    return imgListdef saveRetCropImg(srcImg, area):    # print "saveRetCropImg,area:",area    height,width,chNum = srcImg.shape    area1 = [0,0,area[0], height]    area2 = [area[0],0,area[2], area[1]]    area3 = [area[0], area[3],area[2], height]    area4 = [area[2],0,width, height]    rectList = []    addRect2List(rectList, area1)    addRect2List(rectList, area2)    addRect2List(rectList, area3)    addRect2List(rectList, area4)    imgList = []    for rect in rectList:        img = cutMat(srcImg, rect)        imgList.append(img)    return imgList'''根据设定的灰阶阈值,保存一张新图片,并返回img对象。原图像是BGR模式'''def saveThresholdPicImg(srcImg,threshLow,threshTop, thresholdType):    # print u"转成灰阶图;"    img_gray = cv.cvtColor(srcImg, cv.COLOR_BGR2GRAY)    # print u"转成二值化;"    ret, img_threshold = cv.threshold(img_gray, threshLow, threshTop, thresholdType)    del img_gray    return img_threshold'''检测rect是否正确,正确才添加到rectList'''def addRect2List(rectList, rect):    # print "addRect2List,rect:",rect    if (rect[0] <> rect[2]) and (rect[1] <> rect[3]):        rectList.append(rect)def caculateLinLen(line):    dx = abs(line[0] - line[2])    dy = abs(line[1]-line[3])    # print "caculateLinLen:",dx,dy    lineLen = np.sqrt(np.square(dx) + np.square(dy))    return lineLenclass ImageUtil():    def __init__(self):        pass    '''    根据传入的图像对象,逆时针旋转角度    '''    def rotaImg(self, srcImg, angle):        height, width, color = srcImg.shape        M = cv.getRotationMatrix2D(((height-1)/2.0,(width-1)/2.0),angle,1)        print M        dstImg = cv.warpAffine(srcImg, M, (width,height))        return dstImg    def rotaImg180(self, srcImg):        dstImg = cv.flip(srcImg,0) #根据x轴翻转        dstImg = cv.flip(dstImg,1) #根据y轴翻转        return dstImg    '''    根据传入的图片和高宽差参数,移动图片位置    '''    def transferImg(self, srcImg, dHeight, dWidth):        height,width,color = srcImg.shape        M = np.float32([[1,0,dWidth],[0,1,dHeight]])        dstImg = cv.warpAffine(srcImg,M,(width,height))        return dstImg    '''    根据传入的图片mat和坐标点,计算灰阶中间值    '''    def calGrayMid(self, img, area):        # cv.line(img,(area[0],area[1]),(area[2],area[3]),(0,255,0))        # cv.imshow("img",img)        # cv.waitKey(0)        # cv.destroyAllWindows()        dstArea = list(area)        if area[0] + area[1] > area[2]+area[3]:            dstArea[0] = area[2]            dstArea[1] = area[3]            dstArea[2] = area[0]            dstArea[3] = area[1]        dstImg = cutImage(img, dstArea)        # print "ImageUtil.calGrayAvg: dstImg:",dstImg        return (np.max(dstImg) + np.min(dstImg))/2    '''    根据传入的图片mat和坐标点,计算灰阶平均值    '''    def calGrayAvg(self, img, area):        # cv.line(img,(area[0],area[1]),(area[2],area[3]),(0,255,0))        # cv.imshow("img",img)        # cv.waitKey(0)        # cv.destroyAllWindows()        dstArea = list(area)        if area[0] + area[1] > area[2]+area[3]:            dstArea[0] = area[2]            dstArea[1] = area[3]            dstArea[2] = area[0]            dstArea[3] = area[1]        dstImg = cutImage(img, dstArea)        # print "ImageUtil.calGrayAvg: dstImg:",dstImg        return np.average(dstImg)
 |