主要函数是 ViralInfection , 依一个点为起始点, 逐渐扩散

  
from BLL.ImageVars import ImageVars 
import threading 
import json 
import os 
import os.path 
import time 
import traceback 
import uuid 
import io 
import cv2 
# import torch as torch  
import oss2 
#import paddle 
#import paddlex as pdx 
import urllib3 
import numpy as np 
 
import BLL.Api 
import common 
import BLL.Record  
import common.RemoveBg 
import BLL.VideoHelper 
import Config 
 
from PIL import Image, ImageDraw, ImageFont 
from  common.MyCvTools import cv2imread, cv2imwrite,cv2imdecode 
from common.ColorMap import ColorBGR2RGB, GetCategoriesColor 
 
# from profile.TimeLine import RecordPoint,InitTimeLine,SaveRecord 
from profile.TaskTimeLine import TStart,TEnd,InitTimeLine,SaveRecord,log_time 
import struct 
import logging 
import asyncio 
import traceback 
 
 
 
import matplotlib 
matplotlib.use('TkAgg') 
import matplotlib.pyplot as plt 
import turtle 
 
# 解决中文显示问题 
plt.rcParams['font.sans-serif'] = ['SimHei'] 
plt.rcParams['axes.unicode_minus'] = False 
 
 
 
# @jit(nopython=True) 
def GetCrossIndex(x,y): 
    ''' 
    获取某个点为中心上下左右4个点的坐标 
    ''' 
    return [ 
        [x,y-1],  #上 
        # [x,y],  #中 
        [x,y+1],  #下 
 
        [x-1,y], #左点 
        [x+1,y], #右点 
    ] 
#  
# @jit(nopython=True) 
def GetSudokuIndex(x,y): 
    ''' 
    获取某个点为中心9宫格内上下左右其它8个点的坐标 
    ''' 
    return [ 
        # 第一行的 
        [x-1,y-1], 
        [x-1,y], 
        [x-1,y+1], 
 
        # 第二行的 
        [x,y-1], 
        # [x,y], 排除自身, 
        [x,y+1], 
 
        # 第三行的 
        [x+1,y-1], 
        [x+1,y], 
        [x+1,y+1] 
    ] 
 
# @jit(nopython=True) 
def ViralInfection(img, x:int, y:int): 
    ''' 
    病毒感染传播算法  
    算法原理  
        依某一点为中心逐渐扩大感染范围 
        上下左右8个点依次判断是否跟当前区域相同的色彩值,如果相同的就传染,并作为下一个传染点. 
    ''' 
     
     
    ToBeScannedPoints = [] # List() #queue.Queue() 先进先出队列 
    v = img[x,y] 
    ToBeScannedPoints.append((x,y))  
 
    # plt.show(False) 
 
    while(True): 
    # for p in points: 
         
        # print(len(ToBeScannedPoints)) 
 
        if(len(ToBeScannedPoints) == 0 ): 
            return img 
         
        p = ToBeScannedPoints[0] 
        del ToBeScannedPoints[0] # 取得之后删掉第0个. 就是先进先出的 Queue 
 
        if(p is None): 
            return img 
        x = p[0] 
        y = p[1] 
        # v = p[2] 
        # if (v >= 0): 
        #     continue# 确保扫描的都是负数为中心开始扫描的, 而不是正数开始扫描 
  
        # 取得十字坐标的上下左右8个位置的坐标索引. 
        crossindex = GetCrossIndex(x,y) 
        # 上下左右8个点依次判断是否跟当前区域相同的色彩值,如果相同的就传染,并作为下一个传染点. 
        for xi,yi in crossindex:   
             
            if img[xi,yi] == -v: #感染条件 如果相邻颜色和中心点颜色相反那么会被感染 
               img[xi,yi]  = v #被感染, 
              #  img[xi,yi]  = 0 #被感染后,直接清0,防止再来扫描. 下一个点仍然会按照v来扫描 
               pp = (xi,yi) 
               if pp not in ToBeScannedPoints: #防止重复扫描 
                  ToBeScannedPoints.append(pp)# 放入待检查的列表 
           
 
def V5新算法(record, imgs:BLL.ImageVars): 
     
    '''  
        算法原理,  
            开箱图,为 OImg (open的意思) 
            关厢图,为 CImg (close的意思)  
            第1步, OImg = OImg * -2                   #作用是把关厢图上相应位置的正数变成了负数,两倍的差. 
            第2步, N = CImg + OImg                    #作用是把开箱图上的数据放到对应的关厢图上, 并保留位置信息和分类信息 
            第3步, 将N 中相邻两个非0像素的值互为相反数的正数改成负数. 
            第4步, 将C 中小于N < 0的数值,改成0 
 
    ''' 
    try: 
        if(imgs.OpenImageAiLabelMap is None): 
            return imgs.CloseImageAiLabelMap # 没有开箱图就使用关厢图 
 
        #第1步, N = 0 - CImg[ where OImg > 0]   #作用是把关厢图上相应位置的正数变成了负数. 
        # print(imgs.OpenImageAiLabelMap.shape) 
        O = imgs.OpenImageAiLabelMap.astype('float32') * -2 
        C = imgs.CloseImageAiLabelMap.astype('float32') * 1 
         
        #第2步, 
        N = C + O # 其实是减法运算, 因为前面已经 * -2了.  
 
        #第3步. 加边框   是为了解决最边上的边线会丢失的bug,并且为了防止索引超出边界. 
        N = np.insert(N, 0, values=0, axis=0) 
        N = np.insert(N, 0, values=0, axis=1) 
        N = np.insert(N, N.shape[0], values=0, axis=0) 
        N = np.insert(N, N.shape[1], values=0, axis=1) 
 
        #### 调试用代码 start 
        # print(N.shape) 
  
        plt.figure()  
        plt.title('Open image') 
        plt.imshow(O)  
         
        plt.figure()   
        plt.title('Close image') 
        plt.imshow(C)  
 
        plt.figure()  
        plt.title('diff image') 
        plt.imshow(N)  
 
        #### 调试用代码 end 
 
        #第3步,  将N 中相邻两个非0像素的值互为相反数的正数改成负数. 
        h,w = N.shape 
        for x in range(0,h-1,1):  
            for y in range(0,w-1,1): 
                if N[x,y] < 0 :  # 小于0的负数当做病毒源,开始传播 
                    ViralInfection(N,x,y) 
                    # N[x,y] = 99 
                    # plt.figure()  
                    # plt.title('Viral Infection image') 
                    # plt.imshow(N) 
                    # plt.show() 
         
        plt.figure()  
        plt.title('Viral Infection image') 
        plt.imshow(N) 
        # plt.show() 
      
        N = np.delete(N, 0,   axis=0) 
        N = np.delete(N, 0,   axis=1) 
        N = np.delete(N, -1,  axis=0) 
        N = np.delete(N, -1,  axis=1) 
 
        return imgs.AiDiffMap 
         
    except Exception as ee: 
        traceback.print_exc() 
        return imgs.CloseImageAiLabelMap  
 
 
 
if __name__ == '__main__': 
    image_dir_path = r'./'  # 图片集地址 
    imgs = ImageVars() 
    imgs.OpenImageAiLabelMap  = cv2imread("./image/testimage/62804close.jpg.ai.png") 
    imgs.CloseImageAiLabelMap = cv2imread("./image/testimage/62814close.jpg.ai.png")  
 
    t1 = time.time() 
    V5新算法({}, imgs) 
    t2 = time.time() 
    print("耗时:",t2-t1) 
 
    plt.show()