123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- # -*- coding:utf-8 -*-
- import os, sys, time
- import inspect
- import cv2 as cv
- import numpy as np
- from ssat_sdk.utils import LoggingUtil
- pyFileName = 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 None
- def 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 True
- def saveCropPic(srcPic, destPic, area):
- srcImg = cv.imread(srcPic)
- ret = saveCropImg(srcImg, destPic, area)
- del srcImg
- return ret
- def 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 imgList
- def 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 lineLen
- class 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)
|