Anuj-Panthri's picture
changed objs_found structure
8f7b62d
import cv2
import numpy as np
import matplotlib.pyplot as plt
import math
import copy
import importlib
def tiler(img,image_size,tiles=2,pad=0,):
# pad is 0 to 0.9%
h,w=img.shape[:2]
tile_h=(h//tiles)
tile_w=(w//tiles)
pad=int(tile_h*pad)
crops=[]
coordinates=[]
for i in range(tiles):
for j in range(tiles):
ymin=tile_h*i
xmin=tile_w*j
if i!=0:ymin=ymin-pad
if j!=0:xmin=xmin-pad
ymax=min(ymin+tile_h+pad,h)
xmax=min(xmin+tile_w+pad,w)
# crops.append(img[ymin:ymax,xmin:xmax])
crops.append(cv2.resize(img[ymin:ymax,xmin:xmax],[image_size,image_size]))
coordinates.append((xmin,ymin,xmax,ymax))
# print(crops[-1].shape)
return coordinates,np.array(crops)
class square_crop:
def __call__(self,img):
h,w=img.shape[:2]
self.w_removed,self.h_removed=0,0
if w>h:
self.w_removed=(w-h)//2
img=img[:,self.w_removed:w-self.w_removed]
elif h>w:
self.h_removed=(h-w)//2
img=img[self.h_removed:h-self.h_removed,:]
h,w=img.shape[:2]
self.w_removed,self.h_removed=self.w_removed/w,self.h_removed/h
return img
def rescale(self,objs_found):
raise NotImplementedError
class square_pad:
def __init__(self,color=(0,0,0)):
self.color=color
def __call__(self,img):
h,w=img.shape[:2]
self.w_added,self.h_added=0,0
if h>w:
self.w_added=int((h-w)/2)
padding=(np.ones([h,self.w_added,3])*np.array(self.color)[None,None,:]).astype("uint8")
img=np.concatenate([padding,img,padding],axis=1)
elif w>h:
self.h_added=int((w-h)/2)
padding=(np.ones([self.h_added,w,3])*np.array(self.color)[None,None,:]).astype("uint8")
img=np.concatenate([padding,img,padding],axis=0)
h,w=img.shape[:2]
self.w_added,self.h_added=self.w_added/w,self.h_added/h
return img
def rescale(self,objs_found):
for i in range(len(objs_found)):
objs_found[i][2]=(objs_found[i][2]-self.w_added)/(1-2*self.w_added)
objs_found[i][3]=(objs_found[i][3]-self.h_added)/(1-2*self.h_added)
objs_found[i][4]=(objs_found[i][4])/(1-2*self.w_added)
objs_found[i][5]=(objs_found[i][5])/(1-2*self.h_added)
return objs_found
class face_detection:
def __init__(self,model_path):
################### set num_anchors & tf_anchors ###################
anchor_boxes=np.loadtxt(model_path+"/anchors.txt")
num_anchors=anchor_boxes.shape[0]
tf_anchors=K.reshape(K.variable(anchor_boxes),[1, 1, 1, num_anchors, 2])
load_model_lib.num_anchors=num_anchors
decode_model_lib.tf_anchors=tf_anchors
####################################################################
self.model=load_model(model_path+"/model.h5")
self.modes_available=["tiled","sized"]
self.square_preprocessing=square_crop
config_file_path='.'.join(model_path.split("/"))+".config"
# print(config_file_path)
self.model_config= importlib.import_module(config_file_path)
def invoke_model(self,img,p,iou_threshold,batch_size):
all_objs_found=[]
for i in range(math.ceil(img.shape[0]/batch_size)):
y_pred=self.model.predict(img[int(i*batch_size):int((i+1)*batch_size)].astype('float32'),verbose=0)
# print(y_pred.shape)
for i in range(y_pred.shape[0]):
objs_found=get_objects(y_pred[i],p=p)
all_objs_found.append(objs_found)
return all_objs_found
def get_tiled_output(self,img,p_thres,nms_thres,tiles,pad,image_size,save_tiles=None,batch_size=4):
# pad is 0 to 0.5%
# pad=0.05
img=cv2.resize(img,[image_size*tiles,image_size*tiles])
coordinates,crops=tiler(img,tiles=tiles,pad=pad,image_size=image_size)
all_objs_found=self.invoke_model(crops,p_thres,nms_thres,batch_size)
if save_tiles:
fig=plt.figure(figsize=(3*tiles,3*tiles))
plt.axis("off")
plt.title(f"pad:{pad}")
for i in range(int(tiles*tiles)):
fig.add_subplot(tiles,tiles,i+1)
plt.axis("off")
plt.imshow(pred_image(crops[i],all_objs_found[i]))
# plt.show(block=False)
plt.savefig(save_tiles+f"_{tiles}.jpg")
plt.close()
all_objs_found_joined=[]
for i in range(int(tiles*tiles)):
xmin,ymin,xmax,ymax=coordinates[i]
w,h=xmax-xmin,ymax-ymin
for j in range(all_objs_found[i].__len__()):
# all_objs_found[i][j]['xywh']=np.array(all_objs_found[i][j]['xywh'])/image_size
all_objs_found[i][j]['xywh']=np.array(all_objs_found[i][j]['xywh'])*w
all_objs_found[i][j]['xywh'][0]+=xmin
all_objs_found[i][j]['xywh'][1]+=ymin
all_objs_found[i][j]['xywh']=(all_objs_found[i][j]['xywh']/(image_size*tiles)).tolist()
all_objs_found_joined.extend(all_objs_found[i])
return all_objs_found_joined
def set_mode(self,p_thres,nms_thres,batch_size=1,mode="sized",**kwargs):
# mode : tiled or sized
self.p_thres=p_thres
self.nms_thres=nms_thres
self.batch_size=batch_size
if mode=="tiled":
try:
self.image_size=kwargs['image_size']
if "tiles" not in kwargs:
self.tiles=[1]
self.pad=0
else:
self.tiles=kwargs['tiles'] if(type(kwargs['tiles'])==type(list([1])) or type(kwargs['tiles'])==type(np.zeros([]))) else [kwargs['tiles']]
self.pad=kwargs['pad']
except:
raise ValueError(f"Not all tiled mode parameters passed.")
self.save_tiles=kwargs["save_tiles"] if ("save_tiles" in kwargs) else None
elif mode=="sized":
try:
# self.image_size=kwargs['image_size']
self.image_size=kwargs['image_size'] if(type(kwargs['image_size'])==type(list([1])) or type(kwargs['image_size'])==type(np.zeros([]))) else [kwargs['image_size']]
self.batch_size=1
except:
raise ValueError(f"Not all Sized mode parameters passed.")
else:
raise ValueError(f"Unavailable mode={mode} \nmode can only be one of:{self.modes_available}")
self.mode=mode
def predict_once(self,img):
if (type(img)==str):
img=cv2.cvtColor(cv2.imread(img),cv2.COLOR_BGR2RGB)
elif (type(img)!=type(np.zeros([]))):
raise TypeError(f"Inappropriate type of image={type(img)}")
# if img.shape[0]!=img.shape[1]: raise ValueError(f"The image should be squared")
if not hasattr(self,'mode'): raise ValueError(f"First call set_mode function to set mode using one of the following mode :{self.modes_available}")
if self.mode=='tiled':
if type(self.tiles)==type(list([1])) or type(self.tiles)==type(np.zeros([])): raise TypeError("use advanced_predict function for inference on multiple tiles")
objs_found=self.get_tiled_output(img,p_thres=self.p_thres,nms_thres=self.nms_thres,tiles=self.tiles,pad=self.pad,image_size=self.image_size,save_tiles=self.save_tiles)
elif self.mode=='sized':
if type(self.image_size)==type(list([1])) or type(self.image_size)==type(np.zeros([])): raise TypeError("use advanced_predict function for inference on multiple sizes")
resized_img=cv2.resize(img,[self.image_size,self.image_size])
objs_found=self.invoke_model(resized_img[None,:,:,:],self.p_thres,self.nms_thres,batch_size=1)[0]
return objs_found
def predict(self,img):
if (type(img)==str):
img=cv2.cvtColor(cv2.imread(img),cv2.COLOR_BGR2RGB)
elif (type(img)!=type(np.zeros([]))):
raise TypeError(f"Inappropriate type of image={type(img)}")
img=self.square_preprocessing(img)
if not hasattr(self,'mode'): raise ValueError(f"First call set_mode function to set mode using one of the following mode :{self.modes_available}")
if self.mode=="tiled":
all_objs_found=[]
all_tiles=copy.deepcopy(self.tiles)
for tiles in all_tiles:
self.tiles=tiles
_,objs_found=self.predict_once(img)
all_objs_found.extend(objs_found)
self.tiles=all_tiles
elif self.mode=="sized":
all_objs_found=[]
all_image_size=copy.deepcopy(self.image_size)
for image_size in all_image_size:
self.image_size=image_size
objs_found=self.predict_once(img)
all_objs_found.extend(objs_found)
self.image_size=all_image_size
all_objs_found=np.array(all_objs_found)
all_objs_found=nms(all_objs_found,self.nms_thres)
all_objs_found=self.square_preprocessing.rescale(all_objs_found) #rescale coordinates to original image's resolution
for obj_found in all_objs_found: obj_found[1]=idx_to_class[obj_found[1]]
# print(all_objs_found)
return all_objs_found
if __name__=="__main__":
import create_load_model as load_model_lib
import decode_yolo_v2 as decode_model_lib
from create_load_model import *
from decode_yolo_v2 import *
face_detector=face_detection("face_detection/Models/v1/")
# test_img="C:\\Users\\Home\\Downloads\\WhatsApp Image 2023-01-04 at 6.58.40 PM.jpeg"
test_img="C:\\Users\\Home\\Downloads\\family-52.jpg"
p_thres=0.5
nms_thres=0.3
tiles=3
pad=0
# face_detector.set_mode(p_thres,nms_thres,mode="tiled",tiles=[1,2],pad=pad,image_size=416,save_tiles="tile")
# face_detector.set_mode(p_thres=p_thres,nms_thres=nms_thres,image_size=608)
# face_detector.set_mode(p_thres,nms_thres,mode="sized",image_size=256)
# face_detector.set_mode(p_thres,nms_thres,mode="sized",image_size=352)
# face_detector.set_mode(p_thres,nms_thres,mode="sized",image_size=608)
face_detector.set_mode(p_thres,nms_thres,mode="sized",image_size=1024)
# face_detector.set_mode(p_thres,nms_thres,mode="sized",image_size=[608,1024])
img,objs_found=face_detector.predict(test_img)
# img,objs_found=face_detector.advanced_predict(test_img)
pred_img=pred_image(img,objs_found)
plt.figure()
plt.imshow(pred_img)
plt.show()
# cv2.imwrite("test_output.jpg",pred_img[:,:,::-1])
else:
import face_detection.create_load_model as load_model_lib
import face_detection.decode_yolo_v2 as decode_model_lib
from face_detection.create_load_model import *
from face_detection.decode_yolo_v2 import *