上一讲我说要结合pyqt是因为我以为opencv没有鼠标操作,但是想想就不太可能,因为前面都用过滑条了嘛,那么我随便找了一下,opencv本身就有鼠标事件,不需要在借助pyqt了。
我们重点要学习一个函数,就是setMouseCallback。参考了https://blog.csdn.net/akadiao/article/details/80312254
和https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_mouse_handling/py_mouse_handling.html
opencv里面用的都是回调函数直接写在事件的函数参数里面了,而pyqt是先要发一个信号,然后connect到某一个函数。不过相同点是都会自动传一些参数过去,setMouseCallback传过去的参数有x,y(这个应该是一个像素作为单位的吧),有事件的类型,flags是一些事件标志,param就是上面输入参数的那个param,默认是None。
代码里面比较重要的是ix,iy要用全局变量,这是因为鼠标按下要进一次函数,松开还有再进一次,而函数里面的不加特殊声明的话都是局部变量,局部变量在每一次函数调用结束都要释放空间。所以要声明为全局变量。注意一定不能是waitKey(0),因为这样永远都不会刷新图片了。
我们就先来复现一下:参数得是一个不少才行
这个过程是在矩形的一个角按住鼠标,然后不松开,直到另一个对角,才松开,于是一个矩形就出来了。里面用到了一个画矩形的命令,img就是要在这个图片上显示,也就是这个结果是影响了img的像素的值的,pt1和pt2是对角线上的两点,color就是颜色,是BGR格式的,thickness就是线宽了。这个程序要按esc才能退出。如果线宽是负整数(线宽是小数会报错的)那么就会填充内部,这个下一个例子正好是。不过让我觉得不可思议的是
接下来是画圆的一个程序。
center是确定圆心,上面这个是双击鼠标左键事件,radius是半径,上面是100像素宽吧。
这些鼠标事件就像中断一样,来了就进入回调函数,运行结束后又返回了主循环。之所以要while,是因为这个图片需要一直刷新。
下面来一个稍微复杂的操作:我们既可以画圆,又可以画矩形,,还可以画曲线,一开始画矩形和圆的方式和上面一样,然后按m切换到画曲线模式。
mode这个变量就是用来区分两种模式的。上面画曲线其实用的是画圆,只不过圆的半径比较小。drawing这个是为了控制画曲线的时候,只有按下左键移动才可以画,这样做主要是为了曲线可以中断,比如说我画完了一个8,可以松开鼠标,我要再画一个7,在按下鼠标,这个时候8和7不一定必须连在一起。
这个断断续续的效果其实在我们没开录屏的时候是没有的,应该是因为录屏过程中,鼠标的信号处理就慢了一些。下面来做我想实现的一个功能,就是鼠标双击就可以以双击的那一个点进行泛洪填充。马上来实现一下。
关于loDiff我有一个地方说错了,请到上一讲评论区里看。效果:
关于python我们需要复习一个小知识点,就是容器类型的一个应用。如果在函数里面改变的是容器的内容,例如给容器里面某一个位置重新赋值,那么这个改变是全局的,但是如果是对整个容器做改变,比如下面的列表a重新赋值,那么函数b里的操作不会对函数外的a造成影响,利用这一点,上面声明全局变量的地方,都可以用容器中的某一个值来处理。这就是上面的a会变得原因。
这些操作应该是直接对列表的内存单元进行操作的,还有的比如像a.reverse,也是可以
关于点击右上角×的这件事,我还要说一点:就是虽然它不符合跳出whie循环的条件,也就是销毁不了窗口,但是它可以让鼠标操作无效,可能是释放了鼠标事件的接口,鼠标和cpu通信也就是靠连线或者是无线,鼠标给cpu发送信息,cpu响应,再把数据发送给显示屏显示,我们的鼠标事件肯定是用到了鼠标发给cpu的数据,如果点了x,这个通道就关闭了,这个我是实际试验过的。链接: https://pan.baidu.com/s/1Ipsb8nnxaWOo1BTdZsLCuQ 提取码: zi42
参考了https://blog.csdn.net/qiqiyingse/article/details/81567080
和https://blog.csdn.net/triagen/article/details/60484232
用opencv来录制屏幕。我们需要另外用到一个库,叫做pillow,首先安装一下。
这个如果你有anaconda的话是已经安装过了,当然时可以选择的,我当时安装anaconda是把所有包都选上了。
这里面有一个ImageGrab.grab函数。
grab出来的图片不是numpy.ndarray格式的。所以下面在循环里需要用np.array转换一下。
上面的代码是有一个问题的,就是没有一般手段停下来录制,因为键盘事件必须要有一个窗口,opencv才能接收到,我上面是加了一个imm,但是其实很晕的,看过直播的都知道一开始是无限递归:
所以我们就随便显示一张图片。
录制的视频在链接: https://pan.baidu.com/s/1se4DN1t03dLIVqeOVkc46g 提取码: jm6i
我们还可以用它来直接看一下剪切板的图片。我们都知道QQ截图是在剪切板里卖弄的。
参考了https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_core/py_basic_ops/py_basic_ops.html
和https://blog.csdn.net/real_myth/article/details/53112259
bottom.up.left,right应该是边框的像素宽度。
官方例子:
如果熟悉MATLAB的话,应该会比较熟悉subplot的用法。
颜色有问题时因为BGR和RGB的问题。
全部转化一下,结果就好了。opencv这个BGR的顺序设定还是有点烦的。
这个plt.imshow的'gray'是个什么意思呢?参考了https://blog.csdn.net/goldxwang/article/details/76855200
interpolation是插值的方法,nearest是一种方法,还有其它的linenar啊,cubic啊,等。
还参考了https://blog.csdn.net/htuhxf/article/details/80471442
因为我们的图像是三个维度的所以,其实这个cmap是被忽略的。不要也是可以的。
参考了https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_drawing_functions/py_drawing_functions.html
我们只试一试没有用过的,第一个,画线。
我暂时没看出来cv2.LINE_AA有什么效果。
第二:画椭圆。
axes这里是先给出长轴,然后再给出短轴长。
第三,画多边形:
如果isClosed参数是True,那么图形就是闭合的。这个shift我们一般不用。
reshape那一句完全没有用。False出来的不是闭合的。
用polylines绘制多条线:其实上面已经可以叫绘制多条线了。我在这里试了一下linetype,这个是默认的效果:
这个是cv2.LINE_AA的效果,明显看不出来锯齿了。
但是这种只能画折线啊,不能画不连接的线啊。[20,30]和[70,20]会自动连一条线。
但是其实还是可以画的。需要用下面的形式。n条直线的终点起点用n个数组来放。
第四:向图像添加文字。
org是字符的左下角的位置,fontFace是字体,fontScale是字体缩放因子。
有下面几种字体。
好的,我们先到这里。