小白菜的opencv学习(3)在图像上绘制和写字

小白菜的opencv学习(3)在图像上绘制和写字

我们知道,机器视觉在识别后最直接观察的办法就是画出来,把人物、图形描述出来。今天就学习如何在图像上绘制和写字。文章最后会尝试在摄像头采集的视频中绘制写字。
在图片上绘图的库可以想象有很多很多,我之前用单片机做的一个tft显示屏的库里都有比较成熟的绘图命令。opencv也提供了这样的命令,接下来介绍几个简单比较常用。

cv2.line(img,(0,0),(500,500),(0,255,0),15)

最基础的,画一条线。
在《学习opencv3(中文版)》中,是这样写的:

cv::line()
void line(
cv::Mat&           img,                  //Image to be drawn on
cv::Point          pt1,                  // First endpoint of line
cv::Point          pt2                   // Second endpoint of line
const cv::Scalar&  color,                // Color, BGR form
int                lineType = 8,        // Connectedness, 4 or 8
int                shift    = 0          // Bits of radius to treat as fract
);
cv:line()函数在图像img上绘制一条从pt1到pt2的直线。直线自动被图像边缘截断。

可能是版本不对,该函数实际上有7个参数。
前五个参数很好理解,img图片或者帧,pt1线段开始坐标,pt2线段结束坐标,color线段颜色,thickness线段宽度。这几个参数在上面的参数中都写到了,剩下的两个lineType和shift两个参数不常用。
lineType是线条类型,只能有三种数值(4 or 8 or cv::lineAA),三种类型表示着不同斜线绘制的时候不同算法,可以自行尝试。
shift是亚像素对齐,我没听懂什么意思,看了下注释,相当于缩放了2shift倍,比如(2.5,2.5)像素处画一个点,由于2.5是浮点型,所以程序会报错,而写(5,5)像素并将shift设置为shift=2,那么会将设定的像素点缩小到原来的21倍,就变成了想要的(2.5,2.5)。

第二个绘制矩形。

cv2.rectangle(img,(0,200),(500,150),(0,0,255),10)

几个参数很好理解,图片,两个对角线的坐标,然后是颜色、线宽。同样,矩形的函数中也有lineType,shift两个参数,基本上所有绘图命令都是以这两个参数结尾,下面不再赘述。

第三个绘制圆形。

cv2.circle(img,(500,100),55,(0,255,0),-1)

这里可以发现,线宽变成了-1,像矩形、多边形、圆形这类封闭图形,都可以把线宽改成-1,使图形内部填充满相同颜色。

第四个多边形的绘制。

pts = np.array([[100,5],[100,50],[70,200],[200,100]],np.int32)
cv2.polylines(img, [pts], True, (0,255,255), 3)

多边形的绘制这里是采用将多个像素坐标直线连接的方法。pts变量将多个坐标“打包”,然后用cv2.polylines()命令绘画,这里多了一个实参True,对应的形参是isClosed。如果为真,那么就把第一个点和最后一点连起来,否则就不连接,那么就是is Closed?False!

最后一个,写字。

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV Tuts!',(0,130), font, 1, (200,255,155), 2, cv2.LINE_AA)

font是定义的字体类型,opencv提供了以下几种字体:

标识符描述
CV::FONT_HERSHEY_SIMPLEX普通大小无衬线字体
CV::FONT_HERSHEY_PLAIN小号无衬线字体
CV::FONT_HERSHEY_DUPLEX普通大小无衬线字体
CV::FONT_HERSHEY_COMPLEX比CV::FONT_HERSHEY_SIMPLEX更复杂
CV::FONT_HERSHEY_TRIPLEX普通大小无衬线字体,比cv::FONT_HERSHEY_DUPLEX更复杂
CV::FONT_HERSHEY_COMPLEX_SMALL普通大小无衬线字体,比CV::FONT_HERSHEY_COMPLEX更复杂
CV::FONT_HERSHEY_SCRIPT_SIMPLEX小号版本的CV::FONT_HERSHEY_COMPLEX手写体
CV::FONT_HERSHEY_SCRIPT_COMPLEX比CV::FONT_HERSHEY_SCRIPT_SIMPLEX更复杂的变体

个人感觉最后两种真漂亮
这里的像素点坐标是指字体左上角的像素点。
参数font后面跟的1是fontScale,即字体的高度大小。
接下来的2是字体的粗细。
最后可以发现这里用到的lineType是cv2.LINE_AA型,这个类型是“使用高斯滤波平滑处理的直线”。这个线条类型用来写字看起来会有深有浅,同样画直线时可以使用这种类型来试试看。
最后一个参数bottomLeftOrigin是bool型,默认为False。当这个bool参数为True时,第三个参数的坐标便变成字体右下角的像素点而不是左上角。

现在我们将这些命令画到一张图上面

import numpy as np
import cv2
img = cv2.imread('watch.jpeg',cv2.IMREAD_COLOR)

cv2.rectangle(img,(0,200),(500,150),(0,0,255),10)

cv2.line(img,(0,0),(500,500),(0,255,0),15,8,0)

cv2.circle(img,(500,100),55,(0,255,0),-1)

pts = np.array([[100,5],[100,50],[70,200],[200,100]],np.int32)
cv2.polylines(img, [pts], True, (0,255,255), 3)

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV Tuts!',(0,130), font, 1, (200,255,155), 2, cv2.LINE_AA)

cv2.imshow('image',img)
cv2.waitKey(0)
cv2.imwrite('watchgray.png',img)
cv2.destroyAllWindows()

得到的图片

可以看到我们的手表变得特别丑了。
接下来我们尝试在使用摄像头录制的时候加上这些丑丑的线条。

import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480),True)
font = cv2.FONT_HERSHEY_SCRIPT_COMPLEX
while(True): 
  ret, frame = cap.read()
  cv2.putText(frame,'OpenCV!',(0,130), font, 2, (200,255,155), 2, cv2.LINE_AA)
  out.write(frame)
  cv2.imshow('frame',frame)
  if cv2.waitKey(1) & 0xFF == ord('q'):
    break
    cap.release()
    out.release()
    cv2.destroyAllWindows()

通过之前的视频录制可以写出这样的程序,这里我换了一种更好看的字体。可以自己运行尝试以下。
最后吐槽ubuntu的中文输入法,一堆名词联想不出来……

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值