mkdir -p siammask_base/logs #确保目录名称存在,不存在的就建一个。若不加p,siammask_base 目录不存在,则不能创建logs文件。
python -u #python命令加上- u(unbuffered)参数后会强制其标准输出也同标准错误一样不通过缓存直接打印到屏幕。
详解
3.
from concurrent import futures#为异步执行可调用对象提供了高层接口。
with futures.ProcessPoolExecutor(max_workers=num_threads) as executor:
fs = [executor.submit(crop_video, k, v, set_crop_base_path, set_img_base_path, instanc_size)
for k,v in ytb_vos.items()]
#可以使用 ThreadPoolExecutor 来进行多线程编程,ProcessPoolExecutor 进行多进程编程,两者实现了同样的接口,这些接口由抽象类 Executor 定义。
#寻找一个二值图像的轮廓。注意黑色表示背景,白色表示物体,即在黑色背景里寻找白色物体的轮廓
_, contours, _cv2.findContours(mask,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)#mask (720,1280) 返回(633,1,2)
cnt_area = [cv2.contourArea(cnt) for cnt in contours]#计算轮廓的面积
contour = contours[np.argmax(cnt_area)] # use max area polygon
polygon = contour.reshape(-1, 2)#(136,2)
#rect=cv2.minAreaRect()得到最小外接矩阵的中心(x,y)宽高(w,h)以及旋转角度
#cv2.boxPoints(rect)得到最小外接矩阵的四个顶点坐标 (4,2)
prbox = cv2.boxPoints(cv2.minAreaRect(polygon)) # Rotated Rectangle
# #仿射变换(线性变化加平移)
a = (out_sz-1) / (bbox[2]-bbox[0])#表示水平方向缩放比例
b = (out_sz-1) / (bbox[3]-bbox[1])#要裁剪的边长/bbox的边长
c = -a * bbox[0]#表示水平方向平移的距离
d = -b * bbox[1]
mapping = np.array([[a, 0, c],
[0, b, d]]).astype(np.float)#2x3仿射变换矩阵
crop = cv2.warpAffine(image, mapping, (out_sz, out_sz), borderMode=cv2.BORDER_CONSTANT, borderValue=padding)
return crop
#读取环境
from torch.utils.collect_env import get_pretty_env_info
def collect_env_info():
env_str=get_pretty_env_info()
env_str + ="\n OPenCV ({})".format(cv2.__version__)
returen env_str
#PyTorch version: 0.4.1
#Is debug build: No
#CUDA used to build PyTorch: 9.0.176
#OS: Ubuntu 14.04.5 LTS
#GCC version: (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010
#CMake version: version 3.2.2
#Python version: 3.6
#Is CUDA available: Yes
#CUDA runtime version: Could not collect
#GPU models and configuration:
#GPU 0: GeForce GTX TITAN X
x1, y1, x2, y2 = map(lambda x: x.reshape(self.anchor_num, 1, 1), [x1, y1, x2, y2])
#返回最大score对应的索引值(int)在mask中的位置
best_pscore_id = np.argmax(pscore)
best_pscore_id_mask = np.unravel_index(best_pscore_id, (5, p.score_size, p.score_size))
#设置日志
import logging
def add_file_handler(name, log_file, level = logging.INFO):
logger = logging.getLogger(name)#创建一个logger
fh = logging.FileHandler(log_file)#创建一个handler,用于输出到文件中
fh.setFormatter(get_format(logger, level))#配置日志的格式(此处自定义)
logger.addHandler(fh)#给logger添加handler
#设置余弦函数
window = np.outer(np.hanning(p.score_size), np.hanning(p.score_size))#np.outer计算两个向量的外积,
#拿第一个向量的元素分别与第二个向量所有元素相乘得到结果的一行,如
#A=np.array([1,2,3]),B=np.array([2,3,4]),np.outer(A,B)),输出为:
[[ 2 3 4]
[ 4 6 8]
[ 6 9 12]]
#深度可分离卷积
def conv2d_dw_group(x, kernel):
batch, channel = kernel.shape[:2]
x = x.view(1, batch*channel, x.size(2), x.size(3)) # 1 * (b*c) * k * k
kernel = kernel.view(batch*channel, 1, kernel.size(2), kernel.size(3)) # (b*c) * 1 * H * W
out = F.conv2d(x, kernel, groups=batch*channel)
out = out.view(batch, channel, out.size(2), out.size(3))
return out
最后付几张论文的原话和架构图:
总结:关于anchor的生成和训练label 的设计很巧妙