欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python 图像识别, 模拟病毒感染传播算法

程序员文章站 2024-01-15 19:14:28
...

主要函数是 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()
相关标签: 机器视觉