解决 Faster R-CNN 图片中框不在一张图片上显示的问题
发现问题
在使用demo.py的时候,选取测试用的图片,放到demo,然后修改demo.py中对应的图片名称,然后进行测试:
发现:图片中被框出来的部分并没有完全到一张图片上去,经过多张图片的测试,可以发现,并不是一张图片上一个框,而是按照类别进行的划分,即:每一类一张图片
如何解决这个问题?
原先的画图部分主要在这里:
def vis_detections(im, class_name, dets, thresh=0.5):
"""Draw detected bounding boxes."""
inds = np.where(dets[:, -1] >= thresh)[0]
if len(inds) == 0:
return
im = im[:, :, (2, 1, 0)]
fig, ax = plt.subplots(figsize=(12, 12))
ax.imshow(im, aspect='equal')
for i in inds:
bbox = dets[i, :4]
score = dets[i, -1]
ax.add_patch(
plt.Rectangle((bbox[0], bbox[1]),
bbox[2] - bbox[0],
bbox[3] - bbox[1], fill=False,
edgecolor='red', linewidth=3.5)
)
ax.text(bbox[0], bbox[1] - 2,
'{:s} {:.3f}'.format(class_name, score),
bbox=dict(facecolor='blue', alpha=0.5),
fontsize=14, color='white')
ax.set_title(('{} detections with '
'p({} | box) >= {:.1f}').format(class_name, class_name,
thresh),
fontsize=14)
plt.axis('off')
plt.tight_layout()
plt.draw()
def demo(net, image_name):
"""Detect object classes in an image using pre-computed object proposals."""
# Load the demo image
im_file = os.path.join(cfg.DATA_DIR, 'demo', image_name)
im = cv2.imread(im_file)
# Detect all object classes and regress object bounds
timer = Timer()
timer.tic()
scores, boxes = im_detect(net, im)
timer.toc()
print ('Detection took {:.3f}s for '
'{:d} object proposals').format(timer.total_time, boxes.shape[0])
# Visualize detections for each class
CONF_THRESH = 0.8
NMS_THRESH = 0.3
for cls_ind, cls in enumerate(CLASSES[1:]):
cls_ind += 1 # because we skipped background
cls_boxes = boxes[:, 4*cls_ind:4*(cls_ind + 1)]
cls_scores = scores[:, cls_ind]
dets = np.hstack((cls_boxes,
cls_scores[:, np.newaxis])).astype(np.float32)
keep = nms(dets, NMS_THRESH)
dets = dets[keep, :]
vis_detections(im, cls, dets, thresh=CONF_THRESH)
修改为:
# 将检测可视化
def vis_detections(ax,im, class_name, dets, thresh=0.5):
"""Draw detected bounding boxes."""
#print("+_+")
#print(class_name,dets,thresh)
inds = np.where(dets[:, -1] >= thresh)[0]
print("!!!")
#print(inds) # 是否检测出来东西,如果有的话为0如果没有为空
if len(inds) == 0:
return
#print(im.shape) # 4000 6000 3
#调整通道顺序,如果不调整通道顺序,图像就不正常
for i in inds:
bbox = dets[i, :4]
score = dets[i, -1]
#print(bbox[0],bbox[1],bbox[2],bbox[3])
print("add one patch")
ax.add_patch(
plt.Rectangle((bbox[0], bbox[1]),
bbox[2] - bbox[0],
bbox[3] - bbox[1], fill=False,
edgecolor='red', linewidth=2)
)
ax.text(bbox[0], bbox[1] - 2,
'{:s} {:.3f}'.format(class_name, score),
bbox=dict(facecolor='white', alpha=0.9),
fontsize=8, color='black')
ax.set_title(('{} detections with '
'p({} | box) >= {:.1f}').format(class_name, class_name,thresh),fontsize=12)
def demo(sess, net, image_name):
"""Detect object classes in an image using pre-computed object proposals."""
# Load the demo image
im_file = os.path.join(cfg.FLAGS2["data_dir"], 'demo', image_name)
im = cv2.imread(im_file)
# Detect all object classes and regress object bounds
timer = Timer()
timer.tic()
# detect the picture to find score and boxes
scores, boxes = im_detect(sess, net, im)
# 检测主体部分,在这里加上save_feature_picture
# 这里的net内容是vgg
timer.toc()
print('Detection took {:.3f}s for {:d} object proposals'.format(timer.total_time, boxes.shape[0]))
# Visualize detections for each class
CONF_THRESH = 0.8
NMS_THRESH = 0.3
im = im[:, :, (2, 1, 0)]
fig, ax = plt.subplots(figsize=(10,10))
ax.imshow(im, aspect='equal')
for cls_ind, cls in enumerate(CLASSES[1:]):
cls_ind += 1 # because we skipped background
cls_boxes = boxes[:, 4 * cls_ind:4 * (cls_ind + 1)]
cls_scores = scores[:, cls_ind]
dets = np.hstack((cls_boxes,
cls_scores[:, np.newaxis])).astype(np.float32)
keep = nms(dets, NMS_THRESH)
dets = dets[keep, :]
vis_detections(ax,im, cls, dets, thresh=CONF_THRESH)
plt.draw()
点拨:一开始的时候我也没有发现这两个有什么区别,后来发现图片是按照类别进行区分的以后,就可以看出,demo函数中是按照类别进行划分的,所以只要修改plt位置,将plt从vis_detections中放到demo中,这样所有类都会花在同一个plt中,而不会分开了,这样就解决了这个问题。