| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 | # -*- coding:utf-8 -*-import os,sys,timeimport cv2 as cvimport numpy as npfrom ssat_sdk.utils import LoggingUtilfrom ssat_sdk.picture import image_utilclass PicSegment():    def __init__(self):        pass    '''    在传入的图片上,查找指定bgr颜色框矩形区域,返回矩形区域的坐标    :param picPath:图片路径    :param bgr:颜色值    :return result, contourRect:result=True/False, contourRect:矩形区域    '''    def findAreaByColor(self, srcImg, cropArea, bgr, offset=20, minPeri=0, maxPeri=0, minArea=0, maxArea=0,                                morphology=[]):        # 获取rgb二值图;        img_binary, cropArea = self.getBGRBinaryImage(srcImg, cropArea, bgr, offset)        if img_binary is None:            return False, None        # 查找符合要求的外轮廓;        # opencv3开始,有3个返回值:img, countours, hierarchy        contours = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)[1]        # 是否查找最大轮廓;        bFindMaxContour = False        # 如果周长、面积都一样,只返回最大轮廓;        if minPeri == maxPeri and minArea == maxArea:            bFindMaxContour = True        contourRect = []        maxContour = None  # 最大轮廓;        tempArea = 0        # 过滤掉不符合要求的轮廓;        x, y, w, h, result = 0, 0, 0, 0, False        for cnt in contours:            # 面积;            area = cv.contourArea(cnt)            # 周长;            perimeter = cv.arcLength(cnt, True)            # print "area=%ld, perimeter=%ld"%(area, perimeter)            if bFindMaxContour == True:                # 获取最大轮廓;                if tempArea < area:                    tempArea = area                    maxContour = cnt            else:                # print area,perimeter                # 获取满足条件的值;                if area >= minArea and area <= maxArea and perimeter >= minPeri and perimeter <= maxPeri:                    # 直边矩形,(x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高;                    x, y, w, h = cv.boundingRect(cnt)                    # 在区域内截图判断;                    if cropArea is not None:                        x = x + cropArea[0]                        y = y + cropArea[1]                    contourRect = [x, y, x + w, y + h]                    result = True                    break                # endif        # endfor        if bFindMaxContour == True and maxContour is not None:            result = True            # 最大轮廓的矩形坐标;            x, y, w, h = cv.boundingRect(maxContour)            # 在区域内截图判断;            if cropArea is not None:                x = x + cropArea[0]                y = y + cropArea[1]            contourRect = [x, y, x + w, y + h]        # 只返回结果、轮廓坐标;        return result, contourRect    '''    不做任何图片补足处理的颜色区域处理,和二值化图片获取    '''    def getBGRBinaryImage(self, srcImg, cropArea, bgr, offset=20):        # 读取图片;        if srcImg is None:            return None,None        # 如果截图区域空,使用原图大小;        if cropArea is not None or cropArea.__len__() == 0:            cropArea = [0, 0, srcImg.shape[1], srcImg.shape[0]]        img_crop = None        # 只保留区域部分;        try:            img_crop = image_util.cutImage(srcImg, cropArea)        except:            img_crop = srcImg        subImg = self.subImgBgr(img_crop, bgr)        cv.imwrite(r'd:\\subImg.png', subImg)        subImg_wh1 = np.where((subImg > -offset) & (subImg < offset), np.uint8(0), np.uint8(255))        cv.imwrite(r'd:\\subImg_wh1.png', subImg_wh1)        # 将图处转成灰阶        img_gray = cv.cvtColor(subImg_wh1, cv.COLOR_BGR2GRAY)        # 反转灰度值,以便适合查找轮廓;        img_gray = np.where((img_gray < -offset) | (img_gray > offset), np.uint8(0), np.uint8(255))        # 输出结果图片;        cv.imwrite(r'd:\\img_gray.png', img_gray)        # 使用灰度图求得二值化图;        thresh = cv.threshold(img_gray, 1, 255, cv.THRESH_BINARY)[1]        # 返回二值化图;        return thresh, cropArea    '''    在原有图片,减去固定的BGR颜色值,用于后续的颜色筛选.返回减去bgr的图片。    '''    def subImgBgr(self, bgrImg, bgr):        imgArr = np.asarray(bgrImg).astype(np.int16)        bgrArr = np.asarray(bgr).astype(np.int16)        # 矩阵相减;        subImg = imgArr - bgrArr        return subImg
 |