cv2还原背景图和标注异物

多张识别物根据mask还原背景图

import os
import cv2
import numpy as np
import time

shadow = 0.3
result = "result.png"
dir_img = r"E:\data\road_ab\test\abnormal"
dir_img_mask = r"E:\data\road_ab\ground_truth\abnormal"
img_result = None

def get_mask_img_boxes(path):
    img = cv2.imread(path)
    #cv2.imshow("src_img", img)
    #cv2.waitKey()

    # 中值滤波,去噪
    img = cv2.medianBlur(img, 3)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #cv2.namedWindow('original', cv2.WINDOW_AUTOSIZE)
    #cv2.imshow('original', gray)
    
    # 阈值分割得到二值化图片
    ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    
    # 膨胀操作
    kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    bin_clo = cv2.dilate(binary, kernel2, iterations=2)

    num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_clo, connectivity=8)
    
    # 连通域数量
    #print('num_labels = ',num_labels)
    # 连通域的信息:对应各个轮廓的x、y、width、height和面积
    # print('stats = ',stats)
    # 连通域的中心点
    #print('centroids = ',centroids)
    # 每一个像素的标签1、2、3.。。,同一个连通域的标签是一致的
    #print('labels = ',labels)

    # 不同的连通域赋予不同的颜色
    #output = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
    #for i in range(1, num_labels):
    #    mask = labels == i
    #    output[:, :, 0][mask] = np.random.randint(0, 255)
    #    output[:, :, 1][mask] = np.random.randint(0, 255)
    #    output[:, :, 2][mask] = np.random.randint(0, 255)
    #cv2.imshow('oginal', output)
    #cv2.waitKey()

    boxes = []
    for i in range(1, num_labels):
        boxes.append(stats[i][0:4])
    print('boxes = ',boxes)
    return boxes

def pix_add(img1,img2):
    h = img1.shape[0]
    w = img1.shape[1]
    for i in range(w):
        for j in range(h):
            # img1被挡住了
            if img1[j][i][0] == 255 and img1[j][i][1] == 0 and img1[j][i][2] == 0:
                #img2没有被挡住
                if not(img2[j][i][0] == 255 and img2[j][i][1] == 0 and img2[j][i][2] == 0):
                    img1[j][i] = img2[j][i]
    return img1


def add_background(path_img,path_img_mask):
    print("path_img:",path_img)
    print("path_img_mask:",path_img_mask)
    boxes = get_mask_img_boxes(path_img_mask)
    coordinates = []
    for box in boxes:
        #rect = [[(box[0],box[1]), (box[0]+box[2],box[1]), (box[0]+box[2],box[1]+box[3]), (box[0],box[1]+box[3])]]        
        ws = int(box[2] * shadow)
        hs = int(box[3] * shadow)
        rect = [[(box[0]-ws,box[1]-hs), (box[0]+box[2]+ws,box[1]-hs), (box[0]+box[2]+ws,box[1]+box[3]+hs), (box[0]-ws,box[1]+box[3]+hs)]]
        rect = np.array(rect)
        coordinates.append(rect)
    #print(coordinates)
    src_img = cv2.imread(path_img)
    mask_img = cv2.fillPoly(src_img, coordinates, (255,0,0))
    #cv2.imshow("mask_img", mask_img)
    #cv2.waitKey()

    global img_result
    if not img_result is None:
        #img_result = cv2.imread(result)
        #merge = cv2.add(mask_img,img_result)
        merge = pix_add(img_result,mask_img)
        img_result = merge
        cv2.imwrite(result, merge)
        #cv2.imshow("result", merge)
        #cv2.waitKey()
    else:
        img_result = mask_img
        #cv2.imwrite(result, mask_img)        
        #cv2.imshow("result", mask_img)
        #cv2.waitKey()

def is_done():
    global img_result
    if not img_result is None:
        img = img_result
        h = img.shape[0]
        w = img.shape[1]
        for i in range(w):
            for j in range(h):
                # img1被挡住了
                if img[j][i][0] == 255 and img[j][i][1] == 0 and img[j][i][2] == 0:
                    return False
        cv2.imwrite(result, img_result)
        return True
    return False

def main():
    if os.path.exists(result):
        os.remove(result)
    for img in os.listdir(dir_img):
        path_img = os.path.join(dir_img, img)
        path_img_mask = os.path.join(dir_img_mask, img)
        if os.path.isdir(path_img):
            print("文件夹:", path_img)
        else:
            #print("文件:", path_img)
            add_background(path_img,path_img_mask)
            if is_done():
                break

def test():
    if os.path.exists(result):
        os.remove(result)
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-5.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-5.png")
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-10.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-10.png")
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-15.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-15.png")
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-20.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-20.png")
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-25.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-25.png")
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-30.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-30.png")
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-35.png",r"E:\data\road_ab\ground_truth\abnormal\roi-image-600790-35.png")

def test2():
    if os.path.exists(result):
        os.remove(result)
    add_background(r"E:\data\road_ab\test\abnormal\roi-image-600790-5.png",r"E:\data\data_test\51489114065.jpg")

start = time.time()
#main()
end = time.time()
print(end-start)
#test()
test2()

cv2.destroyAllWindows()

多张识别物根据yolo标注还原背景图

import os
import cv2
import numpy as np
import time
from pathlib import Path

shadow = 0.3
result = "result.png"
img_result = None
imgs = []

class Img:
    def __init__(self, path, boxes, area):
        self.path = path
        self.boxes = boxes
        self.area = area
    def __repr__(self):
        return f"Img(path={self.path}, area={self.area}, boxes={self.boxes})"

def xywhn2xyxy(box, size):
    box = list(map(float, box))
    size = list(map(float, size))
    xmin = (box[0] - box[2] / 2.) * size[1]
    ymin = (box[1] - box[3] / 2.) * size[0]
    w = box[2] * size[1]
    h = box[3] * size[0]
    box = [xmin, ymin, w, h]
    return list(map(int, box))

def get_boxes_and_area(path_label,shape):
    boxes = []
    area = 0
    with open(path_label, 'r') as fid:
        for i in fid.readlines():
            i = i.strip().split()
            # print("i:",i)
            box = xywhn2xyxy((i[1], i[2], i[3], i[4]), shape)
            boxes.append(box)
            area = area + box[2]*box[3]
    return boxes,area

def pix_add(img1,img2):
    # h = img1.shape[0]
    # w = img1.shape[1]
    # for i in range(w):
    #     for j in range(h):
    #         # img1被挡住了
    #         if img1[j][i][0] == 255 and img1[j][i][1] == 0 and img1[j][i][2] == 0:
    #             #img2没有被挡住
    #             if not(img2[j][i][0] == 255 and img2[j][i][1] == 0 and img2[j][i][2] == 0):
    #                 img1[j][i] = img2[j][i]

    done = True
    for box in imgs[0].boxes:
        ws = int(box[2] * shadow)
        hs = int(box[3] * shadow)
        rect = (box[0]-ws, box[1]-hs, box[2]+2*ws, box[3]+2*hs)
        for i in range(rect[0]-2,rect[0]+rect[2]+2):
            for j in range(rect[1]-2,rect[1]+rect[3]+2):
                # img1被挡住了
                if img1[j][i][0] == 255 and img1[j][i][1] == 0 and img1[j][i][2] == 0:
                    done = False
                    #img2没有被挡住
                    if not(img2[j][i][0] == 255 and img2[j][i][1] == 0 and img2[j][i][2] == 0):
                        img1[j][i] = img2[j][i]
    return img1, done


def add_background(img):
    path_img = img.path
    #print("add_background path_img:", path_img)
    boxes = img.boxes
    done = False
    coordinates = []
    for box in boxes:
        ws = int(box[2] * shadow)
        hs = int(box[3] * shadow)
        rect = [[(box[0]-ws,box[1]-hs), (box[0]+box[2]+ws,box[1]-hs), (box[0]+box[2]+ws,box[1]+box[3]+hs), (box[0]-ws,box[1]+box[3]+hs)]]
        rect = np.array(rect)
        coordinates.append(rect)
    #print("coordinates:",coordinates)
    src_img = cv2.imread(path_img)
    mask_img = cv2.fillPoly(src_img, coordinates, (255,0,0))
    #cv2.imshow("mask_img", mask_img)
    #cv2.waitKey()

    global img_result
    if not img_result is None:
        #img_result = cv2.imread(result)
        #merge = cv2.add(mask_img,img_result)
        merge,done = pix_add(img_result,mask_img)
        img_result = merge
        cv2.imwrite(result, merge)
        #cv2.imshow("result", merge)
        #cv2.waitKey(100)
    else:
        img_result = mask_img
        cv2.imwrite(result, mask_img)
        #cv2.imshow("result", mask_img)
        #cv2.waitKey(100)
    return done

# def is_done():
#     global img_result
#     if not img_result is None:
#         img = img_result
#         h = img.shape[0]
#         w = img.shape[1]
#         for i in range(w):
#             for j in range(h):
#                 # img1被挡住了
#                 if img[j][i][0] == 255 and img[j][i][1] == 0 and img[j][i][2] == 0:
#                     return False
#         #cv2.imwrite(result, img_result)
#         return True
#     return False

def main():
    dir_dataset = Path(r"E:\data\background_yolo\bg_handle")
    if os.path.exists(result):
        os.remove(result)
    dir_dataset_images = os.path.join(dir_dataset, "images")
    dir_dataset_labels = os.path.join(dir_dataset, "labels")
    files = os.listdir(dir_dataset_images)
    img0 = cv2.imread(os.path.join(dir_dataset_images, files[0]))
    shape = img0.shape
    print("shape",shape)
    global imgs
    for file in files:
        path_img = os.path.join(dir_dataset_images, file)
        basename = os.path.basename(path_img)
        name = os.path.splitext(basename)[0]
        path_label = os.path.join(dir_dataset_labels, name+".txt")
        #print("path_img",path_img)
        #print("path_label",path_label)
        boxes,area = get_boxes_and_area(path_label,shape)
        img = Img(path_img,boxes,area)
        #print(img)
        imgs.append(img)

    # 排序
    imgs.sort(key=lambda x: x.area)
    for img in imgs:
        print("排序后:",img)
        if add_background(img):
            break

    #cv2.waitKey()
    #cv2.destroyAllWindows()

start = time.time()
main()
end = time.time()
print("cost time:",end-start)

和背景图对比标注识别结果

import os
from re import X
import cv2
import numpy as np
import time
from pathlib import Path
import shutil

debug = 0
dir_roi = Path(r"E:\data\diff\roi")
if os.path.exists(dir_roi):
    shutil.rmtree(dir_roi)
os.makedirs(dir_roi)

def img_resize_to_target_black(image):
    target = np.zeros((512,512),dtype=np.uint8)
    bgr_img = cv2.cvtColor(target, cv2.COLOR_GRAY2BGR)
    h = image.shape[0]
    w = image.shape[1]
    for i in range(h):
        for j in range(w):
            x = int((512 - w)/2)+j
            y = int((512 - h)/2)+i
            bgr_img[y, x, 0] = image[i, j, 0]
            bgr_img[y, x, 1] = image[i, j, 1]
            bgr_img[y, x, 2] = image[i, j, 2]
    return bgr_img

def is_boundary_object(image):
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    image = cv2.threshold(image, 5, 255, cv2.THRESH_BINARY)[1]
    if debug:
        cv2.imshow("is_boundary_object", image)
        cv2.waitKey()
    h = image.shape[0]
    w = image.shape[1]
    print("w:",w,"h:",h)
    #print("image:",image)
    #area = min(w*h/9,10)
    area = w*h/5
    # if area>150:
    #     return False
    count = 0
    for i in range(h):
        for j in range(w):
            #if image[i][j][0] == 0 and image[i][j][1] == 0 and image[i][j][2] == 0:
            if image[i][j] == 0:
                count = count +1
    print("count:",count,"area:",area)
    if count > area:
        return True
    else:
        return False

def diff(img1,img2):
    current_image_gray = cv2.imread(img1,cv2.IMREAD_GRAYSCALE)
    template_image_gray = cv2.imread(img2,cv2.IMREAD_GRAYSCALE)
    #current_image_gray = cv2.imread(img1)
    template_image_color = cv2.imread(img2)

    # current_image_gray = cv2.threshold(current_image_gray, 100, 255, cv2.THRESH_BINARY)[1]
    # template_image_gray = cv2.threshold(template_image_gray, 100, 255, cv2.THRESH_BINARY)[1]
    # cv2.imshow("current_image_gray", current_image_gray)
    # cv2.waitKey()
    # cv2.imshow("template_image_gray", template_image_gray)
    # cv2.waitKey()

    sub_img = cv2.absdiff(current_image_gray, template_image_gray)
    if debug:
        cv2.imshow("absdiff", sub_img)
        cv2.waitKey()
    #thresh = cv2.threshold(sub_img, 30, 255, cv2.THRESH_BINARY)[1]
    #thresh = cv2.adaptiveThreshold(sub_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, -10)
    thresh = cv2.adaptiveThreshold(sub_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 9, 5)

    if debug:
        cv2.imshow("thresh", thresh)
        cv2.waitKey()

    # 中值滤波,去噪
    img = cv2.medianBlur(thresh, 5)
    #gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = img
    cv2.namedWindow('original', cv2.WINDOW_AUTOSIZE)
    if debug:
        cv2.imshow('gray', gray)
        cv2.waitKey()
    
    # 阈值分割得到二值化图片
    # ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    #cv2.imshow('binary', binary)
    #cv2.waitKey()
    
    # 膨胀操作
    kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4))
    bin_clo = cv2.dilate(gray, kernel2, iterations=4)
    if debug:
        cv2.imshow('bin_clo', bin_clo)
        cv2.waitKey()

    num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_clo, connectivity=8)
    
    # 连通域数量
    #print('num_labels = ',num_labels)
    # 连通域的信息:对应各个轮廓的x、y、width、height和面积
    print('stats = ',stats)
    # 连通域的中心点
    #print('centroids = ',centroids)
    # 每一个像素的标签1、2、3.。。,同一个连通域的标签是一致的
    #print('labels = ',labels)

    # 不同的连通域赋予不同的颜色
    #output = np.zeros((current_image_gray.shape[0], current_image_gray.shape[1], 3), np.uint8)
    #for i in range(1, num_labels):
    #    mask = labels == i
    #    output[:, :, 0][mask] = np.random.randint(0, 255)
    #    output[:, :, 1][mask] = np.random.randint(0, 255)
    #    output[:, :, 2][mask] = np.random.randint(0, 255)
    #cv2.imshow('oginal', output)
    #cv2.waitKey()

    boxes = []
    for i in range(1, num_labels):
        boxes.append(stats[i][0:4])
    print('boxes = ',boxes)

    #去掉边界线上的框的结果
    final_boxes = []
    abnormal_num = 10
    abnormal_area = 0.6
    # 数量大于 abnormal_num,或框的面积大于最大面积*abnormal_area时,abnormal为True
    abnormal = False
    # 原图片总面积
    total_area = template_image_color.shape[0] * template_image_color.shape[1]
    abnormal_area = total_area * abnormal_area
    for index,box in enumerate(boxes):
        roi = template_image_color[box[1]:box[1] + box[3], box[0]:box[0] + box[2]]
        roi_resize = cv2.resize(roi, dsize=(box[2]*2, box[3]*2), dst=None, fx=2, fy=2, interpolation=cv2.INTER_NEAREST)
        roi_resize = img_resize_to_target_black(roi_resize)
        #print(roi_resize.shape)
        #cv2.imshow('roi', roi_resize)
        #cv2.waitKey()
        basename = os.path.basename(img2)
        name = os.path.splitext(basename)[0]
        path_roi = os.path.join(dir_roi, name+"_"+str(index)+".jpg") 
        #print("path_roi:",path_roi)
        cv2.imwrite(path_roi, roi_resize)

        # 计算roi内黑色占的部分
        #print(roi)
        if not is_boundary_object(roi):
            final_boxes.append(box)
            if box[2]*box[3] > abnormal_area:
                abnormal = True
    if len(final_boxes) > abnormal_num:
        abnormal = True

    print("最终结果:")
    print("final_boxes = ",final_boxes)
    print("abnormal =",abnormal)

    for index,box in enumerate(final_boxes):
        template_image_color = cv2.rectangle(template_image_color, (box[0], box[1]), (box[0]+box[2], box[1]+box[3]), (0, 0, 255), 1)

    cv2.imshow('oginal', template_image_color)
    cv2.waitKey()

def test_dir():
    #dir_test = Path(r"E:\data\diff\road_test")
    dir_test = Path(r"E:\data\diff\road003")
    files = os.listdir(dir_test)
    for file in files:
        path_img = os.path.join(dir_test, file)
        print("path_img",path_img)
        diff(r"E:\data\diff\road003\roi-image-600790-170.jpg",path_img)

#diff(r"E:\data\diff\road003\roi-image-600790-170.jpg",r"E:\data\diff\road_test\roi-image-600790-1030.jpg")
#diff(r"E:\data\diff\road003\roi-image-600790-170.jpg",r"E:\data\diff\road_test\roi-image-600790-1135.jpg")
diff(r"E:\data\diff\road003\roi-image-600790-170.jpg",r"E:\data\diff\road003\roi-image-600790-100.jpg")
#test_dir()

cv2.destroyAllWindows()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绯虹剑心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值