《Learning Opencv3》第二章 Opencv介绍

第二章 介绍OpenCV


以下是本人阅读《Learning OpenCV3》后的一些体会和笔记,没有详细的全文翻译,恳请批评指正。

一、头文件和命名空间

OpenCV有很多头文件,你可以用opencv.hpp包含所有的OpenCV函数,但此时编译时间就会变长。也可以用各个模块的头文件,例如imgproc.hpp

命名空间using namespace cv;不要忘了,可以不用在OpenCV的函数前面写cv::

二、读取图片和视频

2.1 读取图片

头文件:

头文件highgui.hpp(high-level graphical user interface),用在读取、输入输出、鼠标、按键、滑条中。

Mat 类:

Mat img = imread( argv[1], -1 );Mat类负责图像数据的存储,可以总动分配和释放内存(就像数据结构里面的STL一样)。

显示图像:

namedWindow( "Example 2-1", cv::WINDOW_AUTOSIZE );创建一个窗口。

imshow( "Example 2-1", img );显示图像。

destroyWindow( "Example 2-1" );关闭窗口。

2.2 读取视频

视频是通过for循环,一帧一帧读取的。

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

int main( int argc, char** argv ) {
  cv::VideoCapture cap;
  cap.open( string(argv[1]) );
      cout <<"Opened file: " <<argv[1] <<endl;
  cv::Mat frame;
  for(;;) {
    cap >> frame;
    if( frame.empty() ) break; // Ran out of film
    cv::imshow( "Example 2-3", frame );
    if( (char)cv::waitKey(33) >= 0 ) break;
  }
  return 0;
}

VideoCapture cap;VideoCapture类负责视频的读取。

cap.open( string(argv[1]) );初始化视频的信息,例如大小、路径等

在for循环中使用输出流运算符>>读取视频的帧,并显示每一帧的图像。waitKey(33) >= 0,是指每一帧都应该延时33ms。

三、创建滑动条

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>

using namespace std;

int g_slider_position = 0;//全局滚动变量
int g_run = 1, g_dontset = 0; //start out in single step mode
cv::VideoCapture g_cap;

void onTrackbarSlide( int pos, void *) {
	//回调函数,是当鼠标点击滑动条,也就是触发事件之后就会调用这个函数,就会执行里面的操作
  g_cap.set( CV_CAP_PROP_POS_FRAMES, pos );//设置视频帧位置
  if( !g_dontset ) g_run = 1;
  g_dontset = 0;
}

int main( int argc, char** argv ) {
  cv::namedWindow( "Example 2-4", cv::WINDOW_AUTOSIZE );
  g_cap.open( string(argv[1]) );

  int frames = (int) g_cap.get( CV_CAP_PROP_FRAME_COUNT  );//获取视频总帧数

  int tmpw   = (int) g_cap.get( CV_CAP_PROP_FRAME_WIDTH  );
  int tmph   = (int) g_cap.get( CV_CAP_PROP_FRAME_HEIGHT );

  cout << "Video has " << frames << " frames of dimensions("
       << tmpw << ", " << tmph << ")." << endl;

  cv::createTrackbar("Position","Example 2-4",&g_slider_position,
                     frames,onTrackbarSlide);
     //设置滑动条的位置 并且名为position 在窗口main中显示 滑动条的滑动位置 滑动条的最大值 每次滑动条改变时的回调函数

  cv::Mat frame;

  for(;;) {
    if( g_run != 0 ) {
      g_cap >> frame;
      if(frame.empty()) break;
      int current_pos = (int)g_cap.get( CV_CAP_PROP_POS_FRAMES );//获取视频帧位置

      g_dontset = 1;

      cv::setTrackbarPos("Position", "Example 2-4", current_pos);//设置滑动条位置

      cv::imshow( "Example 2-4", frame );
      g_run-=1;
    }

    char c = (char) cv::waitKey(10);
    if( c == 's' ) { // single step
      g_run = 1;
      cout << "Single step, run = " << g_run << endl;
    }
    if( c == 'r' ) { // run mode
      g_run = -1;
      cout << "Run mode, run = " << g_run <<endl;
    }
    if( c == 27 ) break;
  }
  return(0);
}

VideoCaptureget()和set() 函数可以获得和设置视频信息,控制条的量程被设置成视频总帧数,在控制条回调函数中设置到相应的位置。

四、对图像进行简单处理

4.1 高斯模糊

#include <opencv.hpp>
using namespace cv;

int main() 
{
	Mat image = imread("1.jpg", -1);
	namedWindow("GaussianBlur-out", WINDOW_AUTOSIZE);
	imshow("GaussianBlur-in", image);

	Mat out;
	namedWindow("GaussianBlur-in", WINDOW_AUTOSIZE);
	GaussianBlur(image, out, Size(5, 5), 3, 3);
	GaussianBlur(out, out, Size(5, 5), 3, 3);
	imshow("GaussianBlur-out", out);

	waitKey(0);
	return 0;
}

图像结果如图:在这里插入图片描述

4.2 pyDown

pyrDown 采用高斯金字塔算法来向下采样,对图像进行高斯卷积,将所有偶数行、列去掉,最终将图片大小(长、宽)变为原来的一半。

#include <opencv.hpp>
using namespace cv;

int main() 
{
	Mat img1, img2;
	namedWindow("in", WINDOW_AUTOSIZE);
	namedWindow("out", WINDOW_AUTOSIZE);
	img1 = imread("1.jpg",-1);

	imshow("in", img1);
	pyrDown(img1, img2);
	imshow("out", img2);

	waitKey(0);
	return 0;

};

图像结果如图:在这里插入图片描述

4.3 canny提取边缘

canny函数的两个阈值参数:低于阈值1的像素点会被认为不是边缘;高于阈值2的像素点会被认为是边缘;在阈值1和阈值2之间的像素点,若与第2步得到的边缘像素点相邻,则被认为是边缘,否则被认为不是边缘。

int main() {
	Mat img_rgb, img_gry, img_cny;

	namedWindow("Gray", WINDOW_AUTOSIZE);
	namedWindow("Canny", WINDOW_AUTOSIZE);
	img_rgb = imread("1.jpg");

	cvtColor(img_rgb, img_gry, COLOR_BGR2GRAY);
	imshow("Gray", img_gry);
	//canny(输入,输出,阈值1,阈值2,Sober算子大小)
	Canny(img_gry, img_cny, 50, 100, 3, true);
	imshow("Canny", img_cny);

	waitKey(0);
}

图像结果如图:在这里插入图片描述

五、摄像头输入

和打开视频的操作对比,打开视频中cap.open()中初始化视频信息,摄像头输入是打开默认摄像头cap.open(0);

int main() {
	namedWindow("camera", WINDOW_AUTOSIZE);
	VideoCapture cap;

	cap.open(0);
	Mat frame;
	for (;;) {
		cap >> frame;
		if (frame.empty()) break; // Ran out of film
		imshow("camera", frame);
		if ((char)cv::waitKey(33) >= 0) break;
	}

	return 0;
}

六、输出AVI文件

将视频经过对数变换后输出,效果会做噩梦的。

int main()
{
	namedWindow("Writing AVI File", cv::WINDOW_AUTOSIZE);
	namedWindow("Log_Polar", cv::WINDOW_AUTOSIZE);

	VideoCapture capture("1.avi");
	double fps = capture.get(CV_CAP_PROP_FPS);
	Size size(
		(int)capture.get(CV_CAP_PROP_FRAME_WIDTH),
		(int)capture.get(CV_CAP_PROP_FRAME_HEIGHT)
	);

	VideoWriter writer;
	writer.open("2.avi", CV_FOURCC('M', 'J', 'P', 'G'), fps, size);

	Mat logpolar_frame, bgr_frame;
	for (;;) {
		capture >> bgr_frame;
		if (bgr_frame.empty()) break; // end if done
		imshow("Example 2-11", bgr_frame);
		logPolar(bgr_frame, // Input color frame
			logpolar_frame, // Output log-polar frame
			Point2f( // Centerpoint for log-polar transformation
				bgr_frame.cols / 2, // x
				bgr_frame.rows / 2 // y
			),
			40, // Magnitude (scale parameter)
			CV_WARP_FILL_OUTLIERS // Fill outliers with 'zero'
		);

		imshow("Log_Polar", logpolar_frame);
		writer << logpolar_frame;

		char c = cv::waitKey(10);
		if (c == 27) break; // allow the user to break out

	}
	writer.release();
	capture.release();
}

图像结果如图:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值