多张识别物根据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)
img = cv2.medianBlur(img, 3)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
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)
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):
if img1[j][i][0] == 255 and img1[j][i][1] == 0 and img1[j][i][2] == 0:
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:
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)
src_img = cv2.imread(path_img)
mask_img = cv2.fillPoly(src_img, coordinates, (255,0,0))
global img_result
if not img_result is None:
merge = pix_add(img_result,mask_img)
img_result = merge
cv2.imwrite(result, merge)
else:
img_result = mask_img
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):
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:
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()
end = time.time()
print(end-start)
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()
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):
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):
if img1[j][i][0] == 255 and img1[j][i][1] == 0 and img1[j][i][2] == 0:
done = False
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
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)
src_img = cv2.imread(path_img)
mask_img = cv2.fillPoly(src_img, coordinates, (255,0,0))
global img_result
if not img_result is None:
merge,done = pix_add(img_result,mask_img)
img_result = merge
cv2.imwrite(result, merge)
else:
img_result = mask_img
cv2.imwrite(result, mask_img)
return done
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")
boxes,area = get_boxes_and_area(path_label,shape)
img = Img(path_img,boxes,area)
imgs.append(img)
imgs.sort(key=lambda x: x.area)
for img in imgs:
print("排序后:",img)
if add_background(img):
break
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)
area = w*h/5
count = 0
for i in range(h):
for j in range(w):
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)
template_image_color = cv2.imread(img2)
sub_img = cv2.absdiff(current_image_gray, template_image_gray)
if debug:
cv2.imshow("absdiff", sub_img)
cv2.waitKey()
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 = img
cv2.namedWindow('original', cv2.WINDOW_AUTOSIZE)
if debug:
cv2.imshow('gray', gray)
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('stats = ',stats)
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 = 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)
basename = os.path.basename(img2)
name = os.path.splitext(basename)[0]
path_roi = os.path.join(dir_roi, name+"_"+str(index)+".jpg")
cv2.imwrite(path_roi, roi_resize)
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\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\road003\roi-image-600790-100.jpg")
cv2.destroyAllWindows()