init + inference.py патч

This commit is contained in:
2026-09-12 03:29:38 +03:00
commit 6f7f6031d1
50 changed files with 7410 additions and 0 deletions

View File

@ -0,0 +1,142 @@
import os
import cv2
import numpy as np
# SIZE =256
# BATCH_SIZE = 32
# STRIDES = 256
def split_img(img, size_x, size_y, strides):
max_y, max_x = img.shape[:2]
border_y = 0
if max_y % size_y != 0:
border_y = size_y - (max_y % size_y)
img = cv2.copyMakeBorder(img,border_y,0,0,0,cv2.BORDER_REPLICATE)
# img = cv2.copyMakeBorder(img, border_y, 0, 0, 0, cv2.BORDER_CONSTANT, value=[255,255,255])
border_x = 0
if max_x % size_x != 0:
border_x = size_x - (max_x % size_x)
# img = cv2.copyMakeBorder(img, 0, 0, border_x, 0, cv2.BORDER_CONSTANT, value=[255,255,255])
img = cv2.copyMakeBorder(img,0,0,border_x,0,cv2.BORDER_REPLICATE)
# h,w
max_y, max_x = img.shape[:2]
parts = []
curr_y = 0
x = 0
y = 0
# TODO: rewrite with generators.
while (curr_y + size_y) <= max_y:
curr_x = 0
while (curr_x + size_x) <= max_x:
parts.append(img[curr_y:curr_y + size_y, curr_x:curr_x + size_x])
curr_x += strides
y += 1
curr_y += strides
# parts is a list
# (windows_number_x*windows_number_y,SIZE,SIZE,3)
# print(max_y,max_x)
# print(y,x)
# print(np.array(parts).shape)
return parts, border_x, border_y, max_x, max_y
def combine_imgs(border_x,border_y,imgs, max_y, max_x,size_x, size_y, strides):
# weighted_img
index = int(size_x / strides)
weight_img = np.ones(shape=(max_y,max_x))
weight_img[0:strides] = index
weight_img[-strides:] = index
weight_img[:,0:strides]=index
weight_img[:,-strides:]=index
# 边上
i = 0
for j in range(1,index+1):
# 左上
weight_img[0:strides,i:i+strides] = np.ones(shape=(strides,strides))*j
weight_img[i:i+strides,0:strides] = np.ones(shape=(strides,strides))*j
# 右上
weight_img[i:i+strides,-strides:] = np.ones(shape=(strides,strides))*j
if i == 0:
weight_img[0:strides,-strides:] = np.ones(shape=(strides,strides))*j
else:
weight_img[0:strides,-strides-i:-i] = np.ones(shape=(strides,strides))*j
# 左下
weight_img[-strides:,i:i+strides] = np.ones(shape=(strides,strides))*j
if i == 0:
weight_img[-strides:,0:strides] = np.ones(shape=(strides,strides))*j
else:
weight_img[-strides-i:-i:,0:strides] = np.ones(shape=(strides,strides))*j
# 右下
if i == 0:
weight_img[-strides:,-strides:] = np.ones(shape=(strides,strides))*j
else:
weight_img[-strides-i:-i,-strides:] = np.ones(shape=(strides,strides))*j
weight_img[-strides:,-strides-i:-i] = np.ones(shape=(strides,strides))*j
i += strides
for i in range(strides,max_y-strides,strides):
for j in range(strides,max_x-strides,strides):
weight_img[i:i+strides,j:j+strides] = np.ones(shape=(strides,strides))*weight_img[i][0]*weight_img[0][j]
if len(imgs[0].shape)==2:
new_img = np.zeros(shape=(max_y,max_x))
weight_img = (1 / weight_img)
else:
new_img = np.zeros(shape=(max_y,max_x,imgs[0].shape[-1]))
weight_img = (1 / weight_img).reshape((max_y,max_x,1))
weight_img = np.tile(weight_img,(1,1,imgs[0].shape[-1]))
curr_y = 0
x = 0
y = 0
i = 0
# TODO: rewrite with generators.
while (curr_y + size_y) <= max_y:
curr_x = 0
while (curr_x + size_x) <= max_x:
new_img[curr_y:curr_y + size_y, curr_x:curr_x + size_x] += weight_img[curr_y:curr_y + size_y, curr_x:curr_x + size_x]*imgs[i]
i += 1
curr_x += strides
y += 1
curr_y += strides
new_img = new_img[border_y:, border_x:]
# print(border_y,border_x)
return new_img
def stride_integral(img,stride=32):
h,w = img.shape[:2]
if (h%stride)!=0:
padding_h = stride - (h%stride)
img = cv2.copyMakeBorder(img,padding_h,0,0,0,borderType=cv2.BORDER_REPLICATE)
else:
padding_h = 0
if (w%stride)!=0:
padding_w = stride - (w%stride)
img = cv2.copyMakeBorder(img,0,0,padding_w,0,borderType=cv2.BORDER_REPLICATE)
else:
padding_w = 0
return img,padding_h,padding_w
def mkdir_s(path: str):
"""Create directory in specified path, if not exists."""
if not os.path.exists(path):
os.makedirs(path)
if __name__ =='__main__':
parts, border_x, border_y, max_x, max_y = split_img(im,512,512,strides=512)
result = combine_imgs(border_x,border_y,parts, max_y, max_x,512, 512, 512)

View File

@ -0,0 +1,91 @@
import cv2
# importing required libraries
import numpy as np
import cv2
from skimage.filters import threshold_sauvola
import glob
from tqdm import tqdm
import os
from skimage import io
def SauvolaModBinarization(image,n1=51,n2=51,k1=0.3,k2=0.3,default=True):
'''
Binarization using Sauvola's algorithm
@name : SauvolaModBinarization
parameters
@param image (numpy array of shape (3/1) of type np.uint8): color or gray scale image
optional parameters
@param n1 (int) : window size for running sauvola during the first pass
@param n2 (int): window size for running sauvola during the second pass
@param k1 (float): k value corresponding to sauvola during the first pass
@param k2 (float): k value corresponding to sauvola during the second pass
@param default (bool) : bollean variable to set the above parameter as default.
@param default is set to True : thus default values of the above optional parameters (n1,n2,k1,k2) are set to
n1 = 5 % of min(image height, image width)
n2 = 10 % of min(image height, image width)
k1 = 0.5
k2 = 0.5
Returns
@return A binary image of same size as @param image
@cite https://drive.google.com/file/d/1D3CyI5vtodPJeZaD2UV5wdcaIMtkBbdZ/view?usp=sharing
'''
if(default):
n1 = int(0.05*min(image.shape[0],image.shape[1]))
if (n1%2==0):
n1 = n1+1
n2 = int(0.1*min(image.shape[0],image.shape[1]))
if (n2%2==0):
n2 = n2+1
k1 = 0.5
k2 = 0.5
if(image.ndim==3):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
else:
gray = np.copy(image)
T1 = threshold_sauvola(gray, window_size=n1,k=k1)
max_val = np.amax(gray)
min_val = np.amin(gray)
C = np.copy(T1)
C = C.astype(np.float32)
C[gray > T1] = (gray[gray > T1] - T1[gray > T1])/(max_val - T1[gray > T1])
C[gray <= T1] = 0
C = C * 255.0
new_in = np.copy(C.astype(np.uint8))
T2 = threshold_sauvola(new_in, window_size=n2,k=k2)
binary = np.copy(gray)
binary[new_in <= T2] = 0
binary[new_in > T2] = 255
return binary,T2
def dtprompt(img):
x = cv2.Sobel(img,cv2.CV_16S,1,0)
y = cv2.Sobel(img,cv2.CV_16S,0,1)
absX = cv2.convertScaleAbs(x) # 转回uint8
absY = cv2.convertScaleAbs(y)
high_frequency = cv2.addWeighted(absX,0.5,absY,0.5,0)
high_frequency = cv2.cvtColor(high_frequency,cv2.COLOR_BGR2GRAY)
return high_frequency
im_paths = glob.glob('imgs/*')
for im_path in tqdm(im_paths):
if '_bin.' in im_path:
continue
if '_thr.' in im_path:
continue
if '_gradient.' in im_path:
continue
im = cv2.imread(im_path)
result,thresh = SauvolaModBinarization(im)
gradient = dtprompt(im)
thresh = thresh.astype(np.uint8)
cv2.imwrite(im_path.replace('.','_bin.'),result)
cv2.imwrite(im_path.replace('.','_thr.'),thresh)
cv2.imwrite(im_path.replace('.','_gradient.'),gradient)

View File

@ -0,0 +1,60 @@
import cv2
import numpy as np
import glob
import os
from tqdm import tqdm
import random
import sys
sys.path.append('./data/MBD')
from MBD import mask_base_dewarper
def shadowExtract(cap_im, alb_im):
im = cap_im
alb = alb_im
## Avoid some bad cases
skip = False
im_min = np.min(im,axis=-1)
kernel = np.ones((3,3))
_, mask = cv2.threshold(cv2.cvtColor(alb,cv2.COLOR_BGR2GRAY), 1, 255, cv2.THRESH_BINARY)
mask_erode = cv2.dilate(mask,kernel=kernel)
mask_erode = cv2.erode(mask_erode,kernel=kernel)
mask_erode = cv2.erode(mask_erode,iterations=4,kernel=kernel)
metric = np.min(im_min[mask_erode==255])
metric_num = 0
if metric==0 or metric==1:
metric_num = np.sum(im_min[mask_erode==255]==metric)
if metric_num>=20:
skip = True
pass
# return None
# it is recommended to skip this sample as it will introduce some artifacts.
alb_temp = alb.astype(np.float64)
alb_temp[alb_temp==0] = alb_temp[alb_temp==0]+1e-5
shadow = np.clip(im.astype(np.float64)/alb_temp,0,1)
shadow = (shadow*255).astype(np.uint8)
return shadow,skip
cap_im = cv2.imread('./data/images/2.png')
alb_im = cv2.imread('./data/images/3.png')
## get mask by binarizing alb_im
_, mask = cv2.threshold(cv2.cvtColor(alb,cv2.COLOR_BGR2GRAY), 1, 255, cv2.THRESH_BINARY)
kernel = np.ones((3,3))
mask = cv2.dilate(mask,iterations=2,kernel=kernel)
mask = cv2.erode(mask,iterations=2,kernel=kernel)
## dewarp cap and alb based on the mask by using MBD method
cap_im, _ = mask_base_dewarper(cap_im, mask_im)
alb_im, _ = mask_base_dewarper(alb_im, mask_im)
shadow_im,skip = shadowExtract(cap_im,alb_im) # It is recommended to skip this sample if skip is True. Based on our observations, images that meet this condition often introduce noise.
cv2.imshow('shadow_im',shadow_im)
cv2.imshow('cap_im',cap_im)
cv2.imshow('alb_im',alb_im)
cv2.imshow('mask',mask)
cv2.waitKey(0)