摘抄至:
https://blog.csdn.net/wsp_1138886114/article/details/82945328
https://segmentfault.com/q/1010000010452320/a-1020000010453711
近日写论文时,发现用网上提供的YOLOv3 代码测试图像并检测矩形框时,程序中并没有设置矩形框线宽的参数。但是如果不调整线宽的话,打印出来的黑白色论文,边框效果并不明显。因此搜索了一下如何调整边框宽度的方法,顺便把OpenCV轮廓检测和绘图的方法了解了一下。
cv2.findContours(binary, cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
其中,cv2.findContours() 的第二个参数主要有:
cv2.findContours() 的第三个参数 method为轮廓的近似办法:
返回值: image, contours, hierarchy
需要注意的是,OpenCV自带的轮廓检测函数,参考的论文为90年发表的论文,轮廓检测效果肯定不如近年来先进的轮廓检测算法的结果!算法设计时,可自行编写程序。
"""
x, y, w, h = cv2.boundingRect(img)
参数:
img 是一个二值图
x,y 是矩阵左上点的坐标,
w,h 是矩阵的宽和高
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
img: 原图
(x,y): 矩阵的左上点坐标
(x+w,y+h):是矩阵的右下点坐标
(0,255,0): 是画线对应的rgb颜色
2: 线宽
"""
for i in range(0,len(contours)):
x, y, w, h = cv2.boundingRect(contours[i])
cv2.rectangle(image, (x,y), (x+w,y+h), (153,153,0), 5)
cv2.drawContours()函数
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])
为了看到自己画了哪些轮廓,可以使用 cv2.boundingRect()
函数获取轮廓的范围,即左上角原点,以及他的高和宽。然后用cv2.rectangle()
方法画出矩形轮廓。
new_image=image[y+2:y+h-2,x+2:x+w-2] # 先用y确定高,再用x确定宽
input_dir=("E:/cut_image/")
if not os.path.isdir(input_dir):
os.makedirs(input_dir)
cv2.imwrite( nrootdir+str(i)+".jpg",newimage)
print (i)
使用 cv2.minAreaRect(cnt) ,返回点集cnt的最小外接矩形,cnt是所要求最小外接矩形的点集数组或向量,这个点集不定个数。
其中:
cnt = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]]) # 必须是array数组的形式
rect = cv2.minAreaRect(cnt) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv2.boxPoints(rect)) #通过box会出矩形框
YOLOv3中画轮廓边框的时候,其中并没有线宽的设置,用的是rectangle函数(不知道这个函数是不是属于PIL )。代码如下:
for i in range(thickness):
draw.rectangle(
[left + i, top + i, right - i, bottom - i],
outline=self.colors[c])
最开始读的时候,以为这个函数跟OpenCV中的 cv2.rectangle
函数类似,可以再接参数设置线宽。后来才明白,原来这个里面,thickness
的大小,就代表了线宽。相当于是画thickness
次轮廓框。
这种写法其实还是比较的麻烦的,而且不是很直观,推荐用OpenCV中绘制轮廓的方法:cv2.rectangle()
。