OpenCV3编程入门

opencv 版本2.8.4

1 imread函数

Mat imread (const string& filename, int flags = 1);

1 filename:要载入的图片路径名

2 fiags为载入标识,指定一个加载图像的颜色类型,默认值为1,表示载入三通道的彩色图像。这个参数可以在OpenCV中标识图像格式的枚举体中取值。若为0,灰度图像。若为2:当载入图像的深度为16位或者32位,返回对应深度的图像,否则转换为8位图像再返回。

3因为flags是int类型得到变量,若不在枚举体里取固定的值,可以这样进行:

  • flags>0 返回一个3通道彩色图像

  • flags=0返回灰度图像

  • flags<0返回包含Alpha通道的加载图像

4 注意:若以彩色模式载入图像,解码后的图像会以BGR的通道进行存储,即蓝,绿,红的顺序,不是通常的RGB顺序。

Mat image0 = imread("1.jpg", 2|4) ;//载入无损的原图像
Mat image1 = imread("1.jpg", 0);//载入灰度图
Mat image2 = imread("1.jpg", 199);//载入3通道的彩色图像

2 imshow函数

void imshow (const string& winname, InputArray mat);

1 winname:填需要显示的窗口标识名称。

2 mat:需要显示的图像

  • 如果载入图像是8位无符号类型,就显示图像本来的样子

  • 如果图像是16位无符号类型或32位整型,用像素值除以256,值的范围是[0, 256x256]映射到[0, 255]

  • 如果图像是32位浮点型,像素值要乘以255.该值的范围是[0, 1]映射到[0, 255]。


3 namedWindow()函数

void namedWindow(const string& winname, int flags = WINDOW_AUTOSIZE);

1 name:窗口名字

2 flags:窗口标识

  • WINDOW_NORMAL——用户可以改变窗口大小(没有限制)CV_WINDOW_NORMAL

  • WINDOW_AUTOSIZE——窗口大小自适应,用户不能改变CV_WINDOW_AUTOSIZE

  • WIDNOW_OPENGL——窗口支持OPENGL CV_WINDOW_OPENGL

3 可以用destroyWindow()函数来关闭窗口,不常用


4. imwrite()函数

bool imwrite(const string& filename, InputArray img, const vector<int>& params = vector<int>());

1 filename:要写入的文件名

2 img:填一个mat类型的图像数据

3 params,表示为特定格式保存的编码,一般情况下,不需要填写。

  • 对于JPEG格式的图片,这个参数表示从0到100的图片质量(CV_IMWRITE_JPEG_QUALITY)默认值是95

  • 对于png格式,这个参数表示压缩级别(CV_IMWRITE_PNG_COMPRESSION)从0到9,较高值以为值更小的尺寸和更长的压缩时间,默认值3

  • 对于ppm,pgm,或pbm格式的图片,这个参数表示一个二进制格式标志(CV_IMWRITE_PXM_BINARY)取值为0或1, 默认值是1


5. 滑动条的创建和使用

1 createTrackbar()函数

int createTrackbar(const string& trackbarname, const string& winname, int *valueint count, TrackbarCallback onChange = 0void* userdata = 0);
  • trackbarname:轨迹条的名字

  • winname:窗口的名字,表示这个轨迹条会依附到那个窗口上、

  • value:指向int的指针,表示滑块的位置,滑块的初试位置就是该变量当前的值。

  • count:表示滑块可以达到的最大位置的值。滑块最小位置始终为0

  • trackbarcallback类型的onchange,它有默认值为0.这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void xxxx(int, void*) 其中,第一个参数是轨迹条的位置,第二个参数是用户数据,如果回调是null指针,则表示没有回调函数的调用,仅第三个参数value有变化。

  • userdata也有默认值0, 这个从参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,可以不用管这个参数。

2 getTrackbarPos()函数--用于获取当前轨迹条的位置

int getTrackbarPos(const string& trackbarname, const string& winname);
  • trackbarname:轨迹条的名字

  • winname:轨迹条父窗口的名称

6 鼠标操作

SetMouseCallback函数的作用是为指定的窗口设置鼠标回调函数,原型如下:

void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0);

1 winname:窗口名字

2 onMouse:指定窗口里每次鼠标事件发生的时候,被调用的函数指针。这个函数的原型的大概形式为

void Foo(int event, int x, int y, int flags, void *param)
其中event是EVENT_+变量之一,x和y是鼠标指针在图像坐标系(不是窗口坐标系)中的坐标值,flags是EVENT_FLAG的组合,param是用户定义的传递到setmousecallback函数调用的参数。如EVENT_MOUSEMOVE为鼠标移动消息、EVENT_LBUTTONDOWN为鼠标左键按下消息。

3 userdata:有默认值0.

代码示例

1 图像腐蚀

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc//imgproc.hpp>
using namespace cv;

int main_2()
{
    Mat srcImage = imread("pic.jpg");
    imshow("[原图]腐蚀操作", srcImage);
    Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
    Mat dstImage;
    erode(srcImage, dstImage, element);
    imshow("[效果图]腐蚀操作", dstImage);
    waitKey(0);
    return 0;
}

2 模糊

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;


int main_3()
{
    Mat srcImage = imread("pic.jpg");
    imshow("均值滤波【原图】", srcImage);
    Mat dstImage;
    blur(srcImage, dstImage, Size(7, 7));
    imshow("均值滤波【效果图】", dstImage);
    waitKey(0);
    return 0;
}

3 边缘检测

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;

int main_4()
{
    Mat srcImage = imread("pic.jpg");
    imshow("【原始图】Canny边缘检测", srcImage);
    Mat dstImage, edge, grayImage;
    dstImage.create(srcImage.size(), srcImage.type());//创建与src同类型和大小的矩阵
    //将原图像转换为灰度图像
    cvtColor(srcImage, grayImage, CV_BGR2GRAY);//opecv2 代码版本
    blur(grayImage, edge, Size(3, 3));
    Canny(edge, edge, 3, 9, 3);
    imshow("【效果图】Canny边缘检测", edge);
    waitKey(0);
    return 0;
}

//不知道这里的dstImage是干什么的

4 使用摄像头

#include <opencv2/opencv.hpp>
using namespace cv;

// int main()
// {
//     //VideoCapture capture("1.avi");//读取视频
//     VideoCapture capture(0);//调取摄像头
//     while(1)
//     {
//         Mat frame;
//         capture >> frame;
//         imshow("读取视频", frame);
//         waitKey(1);
//     }
//     return 0;
// }

int main_5()
{
    VideoCapture capture(0);
    Mat edges;
    while(1)
    {
        Mat frame;
        capture >> frame;
        cvtColor(frame, edges, CV_BGR2GRAY);
        blur(edges, edges,Size(7, 7));
        Canny(edges, edges, 0, 30, 3);
        imshow("Canny后的视频", edges);
        if (waitKey(30) >= 0)
        {
            break;
        }
    }
    return 0;
}

5 imwrite使用

#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <vector>

using namespace std;
using namespace cv;

void creatAlphaMat(Mat &mat)
{
    for (int i = 0; i < mat.rows; ++i)
    {
        for (int j = 0; j < mat.cols; ++j)
        {
            Vec4b &rgba = mat.at<Vec4b>(i, j);
            rgba[0] = UCHAR_MAX;
            rgba[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
            rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
            rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
        }
    }
}

int main_6()
{
    Mat mat(480, 640, CV_8UC4);
    creatAlphaMat(mat);//创建带Alpha通道的mat

    vector<int>compression_params;
    //compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);//书中写这句是v2的下面两句是v3的,但是这里库是v248的,要是用下面的代码才能运行成功
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);
    
    try
    {
        imwrite("透明Alpha值图.png", mat, compression_params);
        imshow("生成的png图", mat);
        fprintf(stdout, "png图片文件的alpha数据保存完毕~\n 可以在工程目录下查看由imwrite函数生成的图片\n");
        waitKey(0);
    }
    catch(runtime_error& ex)
    {
        fprintf(stderr, "图像转换成png格式发生错误:%s\n", ex.what());
        return 1;
    }
    return 0;
}

6 混合

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main_7()
{
    Mat girl = imread("girl.jpg");
    namedWindow("[1]动漫图");
    imshow("[1]动漫图", girl);

    Mat image = imread("dota.jpg", 199);
    Mat logo = imread("dota_logo.jpg");
    namedWindow("[2]原画图");
    imshow("[2]原画图", image);
    
    namedWindow("[3]logo图");
    imshow("[3]logo图", logo);

    Mat imageROI;
    imageROI = image(Rect(800, 350, logo.cols, logo.rows));

    addWeighted(imageROI, 0.5, logo, 0.3, 0., imageROI);

    namedWindow("[4]原画+logo图");
    imshow("[4]原画+logo图", image);

    imwrite("由imwrite生成的图片.jpg", image);

    waitKey(0);
    return 0;

}

7 进度条

#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

#define WINDOW_NAME "【线性混合示例】"

const int g_nMaxAlphaValue = 100; //alpha 的最大值
int g_nAlphaValueSlider;//滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;

Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;

void on_Trackbar(int , void*)
{
    //求出当前alpha值相对于最大值的比例
    g_dAlphaValue = (double) g_nAlphaValueSlider / g_nMaxAlphaValue;
    //beta值为1-Alpha
    g_dBetaValue = (1.0 - g_dAlphaValue);
    //根据alpha和beta进行线性混合
    addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
    imshow(WINDOW_NAME, g_dstImage);
}

int main_8()
{
    g_srcImage1 = imread("1.jpg");
    g_srcImage2 = imread("2.jpg");

    if (!g_srcImage1.data)
    {
        printf("读取第一幅图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
        return -1;
    }
    if (!g_srcImage2.data)
    {
        printf("读取第二幅图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
        return -1;
    }

    g_nAlphaValueSlider = 70;//滑动条初值为70
    namedWindow(WINDOW_NAME, 1);

    char TrackbarName[50];
    sprintf(TrackbarName, "透明值 %d", g_nMaxAlphaValue);

    createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);

    on_Trackbar(g_nAlphaValueSlider, 0);
    

    waitKey(0);
    return 0;

}

8 鼠标操作

// StudyOpenCV_10鼠标的使用.cpp: 定义控制台应用程序的入口点。
//
//------------------Rect的知识---------------------

//Rect_类有些意思,成员变量x、y、width、height,分别为左上角点的坐标和矩形的宽和高。
//常用的成员函数有Size()返回值为一个Size,area()返回矩形的面积,contains(Point)用来判断点是否在矩形内,
//inside(Rect)函数判断矩形是否在该矩形内,tl()返回左上角点坐标,br()返回右下角点坐标


//-------------------RNG随机数产生器-------------------------

//RNG类。它可以压缩一个64位的i整数并可以得到scalar和array的随机数。
//目前的版本支持均匀分布随机数和Gaussian分布随机数。随机数的产生采用的是Multiply - With - Carry算法和Ziggurat算法。
//其构造函数的初始化可以传入一个64位的整型参数作为随机数产生器的初值。next可以取出下一个随机数,
//uniform函数可以返回指定范围的随机数,gaussian函数返回一个高斯随机数,fill则用随机数填充矩阵。

#include "stdafx.h"
#include<opencv2/opencv.hpp>

using namespace cv;

#define WINDOW_NAME "【程序窗口】"

//--------------------全局函数声明部分--------------------
void on_MouseHandle(int event, int x, int y, int flage, void *param);
void DrawRectangle( cv::Mat & img, cv::Rect box);


//--------------------全局变量声明部分--------------------
Rect g_rectangle;
bool g_bDrawingBox = false; //是否进行绘制图形
RNG g_rng(12345);  //随机数产生器

int main()
{
	//【1】准备参数
	g_rectangle = Rect(-1, -1, 0, 0);

	//一个长为600, 宽为800的窗口
	//CV_8UC3 是创建----8位无符号的三通道---RGB彩色图像
	Mat srcImage(600, 800, CV_8UC3);

	//设置一个临时变量
	Mat tempImage;

	//将srcImage中的值复制给临时变量tempImage
	srcImage.copyTo(tempImage);

	//将srcImage中的值全部设置为0
	srcImage = Scalar::all(0);

	//【2】设置鼠标操作回调函数
	namedWindow(WINDOW_NAME);

	setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*) &srcImage);

	//【3】程序主循环,当进行绘制的标识符为真时,进行绘制

	/*注意:不能在毁掉函数中写入未初始化的矩阵类,所以需要用时,需要写一个标志位,然后再在while(1)循环内使用*/
	while (1)
	{
		//复制原图到临时变量
		srcImage.copyTo(tempImage);

		if (g_bDrawingBox)//当进行绘制的标识为真,则进行绘制
		{		
			DrawRectangle(tempImage, g_rectangle);
		}

		imshow(WINDOW_NAME, tempImage);

		if (waitKey(10) == 27) //按下esc键,程序退出
		{
			break;
		}
	}

    return 0;
}

//--------------------【on_MouseHandle函数】--------------------
//--------------------鼠标回调函数,根据不同的鼠标事件进行不同的操作--------------------
//----参数解释:
//-------event是 CV_EVENT_*变量之一
			//EVENT_MOUSEMOVE 滑动
			//EVENT_LBUTTONDOWN 左击
			//EVENT_RBUTTONDOWN 右击
			//EVENT_MBUTTONDOWN 中键点击
			//EVENT_LBUTTONUP 左键放开
			//EVENT_RBUTTONUP 右键放开
			//EVENT_MBUTTONUP 中键放开
			//EVENT_LBUTTONDBLCLK 左键双击
			//EVENT_RBUTTONDBLCLK 右键双击
			//EVENT_MBUTTONDBLCLK 中键双击

//------- x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系) 

//------- flags是CV_EVENT_FLAG的组合,flag的状态有:
			//EVENT_FLAG_LBUTTON 左键拖拽
			//EVENT_FLAG_RBUTTON 右键拖拽
			//EVENT_FLAG_MBUTTON 中键拖拽
			//EVENT_FLAG_CTRLKEY 按住Ctrl不放
			//EVENT_FLAG_SHIFTKEY 按住Shift不放
			//EVENT_FLAG_ALTKEY 按住Alt不放
//------- param是用户定义的传递到setMouseCallback函数调用的参数。
void on_MouseHandle(int event, int x, int y, int flage, void *param)
{
	Mat& image = *(cv::Mat*) param;
	switch (event)
	{
		//鼠标移动消息
	case EVENT_MOUSEMOVE: {
		//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
		if (g_bDrawingBox) {

			//g_rectangle.x 是矩形 左上角的x坐标值  g_rectangle.y是矩形 左上角的y坐标值
			g_rectangle.width = x - g_rectangle.x;
			g_rectangle.height = y - g_rectangle.y;

		}
	} break;

		//左键按下消息
	case EVENT_LBUTTONDOWN:
	{
		g_bDrawingBox = true;
		g_rectangle = Rect(x, y, 0, 0);//记录起始点

	}break;

	  //左键抬起消息
	case EVENT_LBUTTONUP:
	{
		//置标识符为false
		g_bDrawingBox = false;

		//对宽和高小于0的处理
		//鼠标移动的方向是从右往左
		if (g_rectangle.width < 0) 
		{
			g_rectangle.x += g_rectangle.width;
			g_rectangle.width *= -1;

		}
		//鼠标移动的方向是从下往上
		if (g_rectangle.height < 0) 
		{
			g_rectangle.y += g_rectangle.height;
			g_rectangle.height *= -1;
		}

		//调用函数进行绘制
		DrawRectangle(image, g_rectangle);
	}break;

        default:
		   break;
	  
	}
}

//--------------------【DrawRectangle()函数】--------------------
//--------------------自定义的矩形绘制函数--------------------
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
	//利用对角线(x,y)和( x+width, y+height )来画矩形
	rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0,255),
		g_rng.uniform(0, 255), g_rng.uniform(0, 255))); //随机颜色

}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值