立即注册 找回密码

微雪课堂

搜索
微雪课堂 树莓派 树莓派OpenCV教程 查看内容

树莓派OpenCV系列教程7:OpenCV中HighGUI及相关上位机开发

2019-10-29 16:39| 发布者: Tornado| 查看: 7022| 评论: 2

摘要: 本章将介绍OpenCV中自带组件HighGUI的简单使用。当我们在测试算法,查看算法效果的时候,需要用到可视化,动态调参的界面,也可能需要监听鼠标,键盘等的动作,这时,HighGUI就发挥大作用了,HighGUI作为OpenCV的图 ...

本章将介绍OpenCV中自带组件HighGUI的简单使用。当我们在测试算法,查看算法效果的时候,需要用到可视化,动态调参的界面,也可能需要监听鼠标,键盘等的动作,这时,HighGUI就发挥大作用了,HighGUI作为OpenCV的图形化(GUI)组件,可以通过HighGUI开发一些简易的上位机。

1 HighGUI所提供的接口类型

OpenCV的HighGUI提供了以下几种接口:

  • 创建多个窗口,在窗口中显示图像
  • 监听鼠标相关的操作
  • 创建按钮,滑块等简单交互组件,并获取其值

下面将分别讲解该接口,最后通过一个综合案例了解该接口的使用。

2 HighGUI窗口

2.1 namedWindow接口

函数原型:

python3

None = cv.namedWindow(winname[, flags])

C++

void cv::namedWindow(const String & winname, int flags = WINDOW_AUTOSIZE )

该函数可以传入一些参数(flags)来实现窗口的一些设定。

设置选项1:窗口大小

  • WINDOW_NORMAL 1 代表允许拖动窗口变换窗口大小。
  • WINDOW_AUTOSIZE 0 默认根据屏幕跟图片的大小, 自动缩放。 不允许手动变化窗口大小。

设置选项2:设置宽高比

  • WINDOW_FREERATIO 256 不固定宽高比。
  • WINDOW_KEEPRATIO 0 默认固定宽高比, 也就是窗口拖拽缩放, 必须保持原来的宽高比。

设置选项3:窗口GUI版本

  • WINDOW_GUI_NORMAL 16 旧版窗口组件。 不支持statusbar跟toolbar。 就是窗口上方的状态栏,工具栏。
  • WINDOW_GUI_EXPANDED 0 默认新版本功能增强的GUI窗口。

一般地,我们想设置可以自由拖动,又不固定宽高比的窗口,那我们可以这样写:

python3

cv2.namedWindow('image_win', flags=cv2.WINDOW_NORMAL|cv2.WINDOW_FREERATIO|cv2.WINDOW_GUI_EXPANDED)

C++

namedWindow("image_win", WINDOW_NORMAL|WINDOW_FREERATIO|WINDOW_GUI_EXPANDED);

2.2 imshow接口

函数原型:

python3

None=cv.imshow(winname, mat)

C++

void cv::imshow(const String & winname,InputArray mat )

在这里,调用imshow函数时,如果”image_win”这个窗口之前并没有被声明,那么会先创建一个名字叫”image_win”的窗口,然后再更新这个窗口里面的图像。

该函数具体使用如下:

python3

cv2.imshow('image_win',img)

C++

imshow("image_win",img)

2.3 窗口销毁

该函数负责销毁窗口,但该函数对于小型项目而言,并不是很有必要,因为一般在程序结束时,会自动销毁窗口。该函数的具体使用如下:

python3

cv2.destroyWindow('image_win')

C++

destroyWindow("image_win")

3 HighGUI鼠标事件监听

3.1 鼠标支持的事件

首先,鼠标支持以下事件:

  • EVENT_MOUSEMOVE 鼠标移动 Mouse Move
  • EVENT_LBUTTONDOWN 鼠标左键点击 Left Button Down
  • EVENT_RBUTTONDOWN 鼠标右键点击 Right Button Down
  • EVENT_MBUTTONDOWN 鼠标中键点击 Middle Button Down
  • EVENT_LBUTTONUP 鼠标左键抬起 Left Button Up
  • EVENT_RBUTTONUP 鼠标右键抬起 Right Button Up
  • EVENT_MBUTTONUP 鼠标中键抬起 Middle Button Up
  • EVENT_LBUTTONDBLCLK 鼠标左键双击 Left Button Double Click
  • EVENT_RBUTTONDBLCLK 鼠标右键双击 Right Button Double Click
  • EVENT_MBUTTONDBLCLK 鼠标中键双击 Middle Button Double Click

3.2 鼠标支持的事件标志

  • EVENT_FLAG_LBUTTON 左键正在按下
  • EVENT_FLAG_RBUTTON 右键正在被按下
  • EVENT_FLAG_MBUTTON 中键正在被按下
  • EVENT_FLAG_CTRLKEY CTRL键正在被按下
  • EVENT_FLAG_SHIFTKEY SHIFT键正在被按下
  • EVENT_FLAG_ALTKEY ALT键正在被按下

3.3 鼠标事件回调函数及其设置

将通过一个案例来了解该函数的具体使用,在该案例中,只有当鼠标在移动,并且Ctrl和鼠标左键同时按下时,才打印出相关信息:

Python3:

#That is actually what callback function define
def onMouse(event,x,y,flags,param): 
    if event == cv2.EVENT_MOUSEMOVE and flags == (cv2.EVENT_FLAG_LBUTTON|cv2.EVENT_FLAG_CTRLKEY ):
        #Judged, then in this occasion, do something
        print(x)
        print(y)
        print(event)
        print(flags)

# Set the callback function
cv2.setMouseCallback('image', onMouse)

C++:

//That is actually what callback function define
static void onMouse( int event, int x, int y, int flags, void* )
{
    if(event==EVENT_MOUSEMOVE)&&(flags==(EVENT_FLAG_LBUTTON|EVENT_FLAG_CTRLKEY))
    {
        //Judged, then in this occasion, do something
        printf("%d\r\n",x);
        printf("%d\r\n",y);
        printf("%d\r\n",event);
        printf("%d\r\n",flags);
    }
}
setMouseCallback("image", onMouse);

在回调函数中:

  • event 鼠标事件类型,详见3.1中鼠标支持的事件
  • x 鼠标当前在窗口Windows下的x坐标
  • y 鼠标在当前窗口Windows下的y坐标
  • flags 鼠标事件发生过程值中的一些其他事件标志/状态,详见3.2中鼠标支持的事件标志
  • param 用户自定义的参数

4 HighGUI滑动条组件

将通过一个案例来演示如何使用滑动组件,在本案例中,首先通过简单案例演示滑动组件的基本使用,接着,来做一个彩色画布。

4.1 python3实现

简单案例,先演示如何使用滑动组件。

import cv2

# 创建窗口
cv2.namedWindow('image_win')

# 定义全局变量
value = (0, 0, 0)

# 定义回调函数
def update(x):
    global value
    r_value = cv2.getTrackbarPos('R','image_win')
    g_value = cv2.getTrackbarPos('G', 'image_win')
    b_value = cv2.getTrackbarPos('B', 'image_win')

    value = (r_value, g_value, b_value)
    print('Update Value, value ={}'.format(value))

# 创建滑动组件
cv2.createTrackbar('R','image_win',0,255,update)
cv2.createTrackbar('G','image_win',0,255,update)
cv2.createTrackbar('B','image_win',0,255,update)

# 设置默认值
cv2.setTrackbarPos('R','image_win',125)
cv2.setTrackbarPos('G','image_win',125)
cv2.setTrackbarPos('B','image_win',125)

# 等待按键按下
cv2.waitKey(0)

# 销毁窗口
cv2.destroyAllWindows()

程序运行后的GUI界面如下图所示:

下面进阶案例,演示如何实现可变色画布

import cv2
import numpy as np

canvas = np.zeros((300,300,3), np.uint8)

color = (0, 0, 0)

# 更新图片,在更新颜色回调函数中调用
def updateImage():
    global color
    canvas[:,:] = color
    cv2.imshow('image',canvas)

# 更新颜色回调函数
def updateColor(x):
    global color
    r_value = cv2.getTrackbarPos('Channel_Red','image')
    g_value = cv2.getTrackbarPos('Channel_Green','image')
    b_value = cv2.getTrackbarPos('Channel_Blue','image')
    color = (b_value,g_value,r_value)
    print('Update Value, value={}'.format(color))
    updateImage()

# 新建窗口
cv2.namedWindow('image')

# 创建滑条,并设置回调函数
cv2.createTrackbar('Channel_Red','image',0,255,updateColor)
cv2.createTrackbar('Channel_Green','image',0,255,updateColor)
cv2.createTrackbar('Channel_Blue','image',0,255,updateColor)
# 设置滑条初始化位置
cv2.setTrackbarPos('Channel_Red','image',125)
cv2.setTrackbarPos('Channel_Green','image',125)
cv2.setTrackbarPos('Channel_Blue','image',125)

print("进入RGB滑块实验, 键盘摁q退出程序")

# 首次初始化窗口的色块
# 后面的更新 都是由getTrackbarPos产生变化而触发
updateImage()

while cv2.waitKey(0) != ord('q'):
    continue

cv2.destroyAllWindows()

程序运行后,运行结果如下图所示,拖动滑动条即可进行调色:

4.2 C++实现

其C++实现如下所示,其中像素点的操作没有Python中Numpy的操作那么便捷,采用的是容器访问像素点。

#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

#define WINDOW_NAME "image"

using namespace std;
using namespace cv;

int r_value = 125;
int g_value = 125;
int b_value = 125;

Mat canvas(300,300,CV_8UC3,Scalar(125,125,125));

void updateColor(int, void *)
{
    for(int row=0; row < canvas.rows; row++)
    {
        for(int col = 0; col < canvas.cols; col++)
        {
            canvas.at<Vec3b>(row,col)[0] = (unsigned char)b_value;
            canvas.at<Vec3b>(row,col)[1] = (unsigned char)g_value;
            canvas.at<Vec3b>(row,col)[2] = (unsigned char)r_value;
        }
    }
    imshow(WINDOW_NAME,canvas);
}

int main()
{
    namedWindow(WINDOW_NAME, WINDOW_NORMAL|WINDOW_FREERATIO);
    imshow(WINDOW_NAME,canvas);
    createTrackbar("Channel_Red", WINDOW_NAME, &r_value,255,updateColor);
    createTrackbar("Channel_Green", WINDOW_NAME, &g_value,255,updateColor);
    createTrackbar("Channel_Blue", WINDOW_NAME, &b_value,255,updateColor);
    waitKey();
    return 0;
}

代码执行效果如下图所示:

5 用滑条模拟按键

在OpenCV中,按键组件是不存在的,一种比较主要的实现按键的方法是采用滑条组件来实现按键。

首先演示其实现的Python代码

import cv2

cv2.namedWindow('image_win')

def do_something():
    print('Button Pressed!!')
    print('Do Something')

def update(x):
    if x == 1:
        do_something()
        cv2.waitKey(500)
        cv2.setTrackbarPos('button', 'image_win', 0)

cv2.createTrackbar('button','image_win',0,1,update)

cv2.waitKey(0)

cv2.destroyAllWindows()

其相应的实现效果如下图所示:

相应的,其C++代码如下所示:

#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

#define WINDOW_NAME "image_win"

int position = 0;

using namespace std;
using namespace cv;

void do_something()
{
    cout<<"Button Pressed"<<endl;
    cout<<"Do Something"<<endl;
}

void update(int, void *)
{
    if(position == 1)
    {
        do_something();
        waitKey(500);
        setTrackbarPos("button",WINDOW_NAME,0);
    }
}

int main()
{
    namedWindow(WINDOW_NAME, WINDOW_NORMAL|WINDOW_FREERATIO);
    createTrackbar("button", WINDOW_NAME, &position, 1,update);
    waitKey();
    return 0;
}

其实现效果同Python。


175

顶一下

刚表态过的朋友 (175 人)

相关阅读

发表评论

最新评论

引用 游客 2020-4-1 15:28
运行python示例有报错
    cv2.imshow('Camera Capture',CannyImage)
cv2.error: OpenCV(4.1.0) /home/pi/software/opencv/modules/highgui/src/window.cpp:627: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'
引用 游客 2020-1-13 16:05
感谢

查看全部评论(2)

基础入门
OpenCV
littleGL

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2024-3-19 16:42 , Processed in 0.047523 second(s), 32 queries .

返回顶部