学习OpenCV-(1)-安装与初探

学习OpenCV-(1)-安装与初探

1.概述

OpenCV是用C和C++编写的开源计算机视觉库,可以在Windows、linux、Mac OS等系统上运行。同时它提供了Python、Java、Matlab等其他一些语言的接口,将库导入安卓和iOS中为移动设备开发应用。

OpenCV的一个目标是提供易于使用的计算机视觉接口,帮助人们快速建立精巧的视觉应用。OpenCV库包含从计算机视觉各个领域衍生出来的500多个函数,包括工业产品质量检验、医学图像处理、安保领域、交互操作、相机校正、双目视觉以及机器人学。因为计算机视觉经常和机器学习一起使用,所以OpenCV也包含一个完备的,具有通用性的机器学习库(ML模块)。

OpenCV的开源许可允许任何人利用OpenCV包含的任何组件构建商业产品。

下载和安装

在OpenCV的官方网站可以下载最新的且完整的源码及大部分release版本源码。但是我发现OpenCV的官网打不开,这时我们可以在github(https://github.com/opencv/opencv/releases)上下载exe文件。下载后打开安装很快就完成了。注意安装的时候记住安装路径。安装后在文件管理器打开它的安装文件。应该是如下图内容。

在这里插入图片描述

接下来就需要配置visual studio了。我用的是vs2019,不同版本的vs可能具体配置也不同,vs2017的用户可以参考https://blog.csdn.net/qq_41498261/article/details/83822094?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task来完成配置。

流程:

  1. 新建C++控制台应用
    在这里插入图片描述

  2. 将x86改为x64
    在这里插入图片描述

  3. 视图->属性管理器-> Debug|x64,右击添加新项目属性表,位置最好选择一个好找的位置,名字可以命名为 opencv.props。

  4. 双击添加的属性表开始配置。通用属性->VC++目录->包含目录->编辑,如下图
    在这里插入图片描述

选择库目录,编辑
在这里插入图片描述

  1. 链接器->输入->附加依赖项,输入opencv_world341d.lib
    在这里插入图片描述

  2. 这样就算配置玩了,测试一下代码能不能正常运行

#include <iostream>
#include<opencv2/opencv.hpp>
int main()
{
    cv::Mat img = cv::imread("Hakurei Reimu.png");//图片路径
    if (img.empty())return -1;
    cv::namedWindow("test", cv::WINDOW_AUTOSIZE);
    cv::imshow("test", img);
    cv::waitKey(0);
    cv::destroyWindow("test");
    return 0;
}

注意图片路径要是一个有效的路径,为了避免出错可以将你的一个本地图片复制粘贴到cpp源文件同目录下,这样你就可以直接输入文件名了。最后运行成功的话会出来一个窗口显示相应的图片。
在这里插入图片描述

属性表保存好了以后,再新建控制台应用只需要在属性管理器Debug|x64右键选择添加现有属性表添加前面新建的属性表就完事了。

OpenCV所拥有的模块

  • Core:基础结构以及基本操作
  • Improc:图像处理模块,包含基本的图像转换,包括滤波以及类似的卷积操作
  • Highgui(在OpenCV3.0中分割成imcodecs、videoio以及highgui三部分):包含用来显示图像或者简单的输入的用户交互函数。可以看作一个轻量级的Windows UI工具包
  • Video:包含读取和写视频流函数
  • Calib3d:包含校准单个、双目以及多个相机的算法实现
  • Feature2d:包含用于检验、描述以及匹配特征点的算法
  • Objectect:包含检测特定目标,如人脸或者行人的算法。可以训练检测器并用来检测其他物体。
  • M1:机器学习模块本身是一个非常完备的模块,包含大量的机器学习算法实现并且这些算法都能和OpenCV的数据类型自然交互
  • Flann:快速最近邻库。包含一些也许不会直接使用但其他模块中的函数会调用在数据集中进行最近邻搜索的算法
  • GPU(在OpenCV3.0中被分割成多个cuda*模块):函数在CUDA GPU上的优化实现
  • Photo:计算机摄影学的一些函数
  • Stitching:精巧的图像拼接流程实现
  • Nonfree(在OpenCV3.0中融合进了opencv_contrib/xfeatures2d):一些受到专利保护的或者受到使用限制的(比如SIFT算法)算法
  • Contrib(在OpenCV3.0中融合进了opencv_contrib):包含一些新的还没有被集成进OpenCV库的东西
  • Legacy(在OpenCV3.0被取消):包含一些老的还没有被取消的东西
  • 0cl(在OpenCV3.0被取消,取而代之的是T-API):可以认为它和GPU相似,实现了开放并行编程的Khronos OpenGL标准。

2.初探

1.显示图片

我们在来看一下前面的哪个测试程序

#include <iostream>
#include<opencv2/opencv.hpp>
int main()
{
    cv::Mat img = cv::imread("Hakurei Reimu.png");//图片路径
    if (img.empty())return -1;
    cv::namedWindow("test", cv::WINDOW_AUTOSIZE);
    cv::imshow("test", img);
    cv::waitKey(0);
    cv::destroyWindow("test");
    return 0;
}

首先OpenCV的函数都位于命名空间cv下,如果想省略cv::,可以在前面用using namespace cv。但这样存在与其他命名空间冲突的风险。

函数imread()根据文件名来决定图像格式的处理,也会自动申请图像需要的内存,它可以读取很多种图像格式,函数返回一个Mat结构,这个结构是OpenCV中你会接触的最多的自带结构,OpenCV用这个结构来处理所有类型的图像:单通道、多通道、整型、浮点数以及各种类型。

函数namedWindow由HighGUi模块提供,将一个名称赋予窗口。第二个参数说明了Windows的特性。默认情况下全部设置为0,也可以设置为WINDOW_AUTOSIZE,这样窗口的大小会和载入图像的大小一致,图像会被缩放以使用窗口。

通过imshow()来进行显示。imshow()将建一个窗口。(如果窗口不存在他会自动调用namedWindow()新建一个窗口)。调用imshow()时窗口将被重绘上要求的图片,并且窗口会自动调整大小(使用参数WINDOW_AUTOSIZE)。

waitkey(0)函数告诉系统暂停并等待键盘事件。如果传入参数大于0则会意味着程序等待的毫秒数,比如waitkey(100)就是等待100毫秒,如果100毫秒没有键盘事件就会继续执行程序。0或负数表示等待无限长时间。

最后用函数destroywindow()来让窗口自行销毁。

2.显示视频

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
int main(int argc, char** argv) {
	namedWindow("test", WINDOW_AUTOSIZE);
	VideoCapture cap;
	cap.open("灵梦.mp4");
	Mat frame;
	for (;;) {
		cap >> frame;
		if (frame.empty())break;
		imshow("test", frame);
		if (waitKey(33) >= 0)break;
	}
	return 0;
}

由于上面的程序无法在视频中进行跳转,所以我们需要添加一个滑动条来实现视频跳转。

下面就是一个稍微复杂的程序

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include<iostream>
#include<fstream>
using namespace cv;
using namespace std;
int g_slider_position = 0;
int g_run = 1, g_dontset = 0;
VideoCapture g_cap;
void onTrackbarSlide(int pos, void*) {
	g_cap.set(CAP_PROP_POS_FRAMES, pos);
	if (!g_dontset)
		g_run = 1;
	g_dontset = 0;
}
int main(int argc, char** argv) {
	namedWindow("test", WINDOW_AUTOSIZE);
	g_cap.open("灵梦.mp4");
	int frames = (int)g_cap.get(CAP_PROP_FRAME_COUNT);
	int tmpw = (int)g_cap.get(CAP_PROP_FRAME_WIDTH);
	int tmph = (int)g_cap.get(CAP_PROP_FRAME_HEIGHT);
	cout << "Video has " << frames << " frames of dimension (" << tmpw << " , " << tmph << " )." << endl;
	createTrackbar("Position", "test", &g_slider_position, frames, onTrackbarSlide);
    //不难发现传入的参数分别是 --> name(命名),窗口,事件类型,事件相关联的响应函数
	Mat frame;
	for (;;) {
		if (g_run != 0) {
			g_cap >> frame;
			if (frame.empty())break;
			int current_pos = (int)g_cap.get(CAP_PROP_POS_FRAMES);
			g_dontset = 1;
			setTrackbarPos("Position", "test", current_pos);
			imshow("test", frame);
			g_run -= 1;
		}
		char c = (char)waitKey(10);
		if (c == 's') {
			g_run = 1;
			cout << "Single step,run= " << g_run << endl;
		}
		if (c == 'r') {
			g_run = -1;
			cout << "Run mode, run= " << g_run << endl;
		}
		if (c == 27)break;//ESC
	}
	return 0;
}

在这里插入图片描述

它允许用户按下s键来执行单步模式,按下r键恢复连续视频播放模式。然和时候都可以通过滑动条跳转到视频一个新的时间点,我们用单步模式在那个时间点播放。

程序中用createTrackbar()来创建一个滑动条。这些代码理解起来没有太大困难。

3.简单的变换

接下来我们会对视频中的每一帧实现一些简单的操作。

一个最简单的操作就是对图像的平滑处理,通过高斯核或者其他核卷积效减小图像的信息量。

如下代码在第一个代码的基础上做了一下修改,得到两个窗口,一个显示原图,一个显示处理后的图(图像被5*5大小的高斯核模糊并且被写入out变量中)。高斯核的大小必须是奇数。程序执行了两次模糊操作

#include <iostream>
#include<opencv2/opencv.hpp>
int main()
{
    cv::namedWindow("in", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("out", cv::WINDOW_AUTOSIZE);
    cv::Mat img = cv::imread("Hakurei Reimu.png");//图片路径
    if (img.empty())return -1;
    cv::imshow("in", img);
    cv::Mat out;
    cv::GaussianBlur(img, out, cv::Size(5, 5), 3, 3);
    cv::GaussianBlur(out, out, cv::Size(5, 5), 3, 3);
    cv::imshow("out", out);
    cv::waitKey(0);
    return 0;
}

在这里插入图片描述

4.不那么简单的变换

这里我们先用pyrDown()来创建一个新的图像,其宽高均为原始图像的一半

#include <iostream>
#include<opencv2/opencv.hpp>
int main()
{
    cv::namedWindow("in", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("out", cv::WINDOW_AUTOSIZE);
    cv::Mat img1 = cv::imread("Hakurei Reimu.png");//图片路径
    if (img1.empty())return -1;
   
    cv::Mat img2;
    cv::imshow("in", img1);
    cv::pyrDown(img1, img2);
    cv::imshow("out", img2);
    cv::waitKey(0);
    return 0;
}

在这里插入图片描述

下面我们用Canny边缘检测器输出一个单通道的(灰色)图像,其中边缘检测器通过cvtColor()函数生成一个和原图一样大小但只有一个通道的图像,从而将图像从BGR图像转换为灰度图,这个操作在OpenCV中定义为宏COLOR_BGR2GRAY。

#include <iostream>
#include<opencv2/opencv.hpp>
int main()
{
    cv::namedWindow("gray", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("canny", cv::WINDOW_AUTOSIZE);
    cv::Mat img1 = cv::imread("Hakurei Reimu.png");//图片路径
    if (img1.empty())return -1;
   
    cv::Mat img_gry,img_cny;
    cv::cvtColor(img1, img_gry, cv::COLOR_BGR2GRAY);
    cv::imshow("gray", img_gry);
    cv::Canny(img_gry, img_cny, 10, 100, 3, true);
    cv::imshow("canny", img_cny);
    cv::waitKey(0);
    return 0;
}

在这里插入图片描述

这里我们可以将这些操作组合起来,比如对图像收缩两次再寻找其边缘。然后通过一个简单的方法来读取结果的像素值

#include <iostream>
#include<opencv2/opencv.hpp>
int main()
{
    cv::namedWindow("gray", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("canny", cv::WINDOW_AUTOSIZE);
    cv::Mat img1 = cv::imread("Hakurei Reimu.png");//图片路径
    if (img1.empty())return -1;
   
    cv::Mat img_gry,img_cny,pyr,pyr2;
    cv::pyrDown(img1, pyr);
    cv::pyrDown(pyr, pyr2);
    cv::cvtColor(pyr2, img_gry, cv::COLOR_BGR2GRAY);
    cv::imshow("gray", img_gry);
    cv::Canny(img_gry, img_cny, 10, 100, 3, true);
    cv::imshow("canny", img_cny);
    int x = 16, y = 32;
    cv::Vec3b intensity = img1.at<cv::Vec3b>(y, x);
    uchar blue = intensity[0];
    uchar green = intensity[1];
    uchar red = intensity[2];
    std::cout << "At(x,y)=(" << x << "," << y << "):(blue,green,red)=("
        << (unsigned int)blue << ", " << (unsigned int)green << " , " << (unsigned int)red
        << ")" << std::endl;
    std::cout << "Gray pixel there is:" << (unsigned int)img_gry.at<uchar>(y, x) << std::endl;
    x /= 4; y /= 4;
    std::cout << "Pyramid2 pixel there is" << (unsigned int)pyr2.at<uchar>(y, x) << std::endl;
    img_cny.at<uchar>(x, y) = 128;

    cv::waitKey(0);
    return 0;
}

5.从摄像头中读取

int main(int argc,char** argv)
{
    cv::namedWindow("test", cv::WINDOW_AUTOSIZE);
    cv::VideoCapture cap;
    if (argc == 1) {
        cap.open(0);
    }
    else {
        cap.open(argv[1]);
    }
    if (!cap.isOpened()) {
        std::cerr << "could not open capture" << std::endl;
        return -1;
    }
    cv::waitKey(0);
    return 0;
}

同一个对象可以读取时评文件也可以连接摄像头。

连接一个摄像头需要给它一个相机ID号(如果只有一个摄像头连接,这个ID通常为0),ID的默认值为-1,这意味着随意选择一个。

6.写入AVI文件

我们可以创建一个写入对象将帧一次输入到一个视频文件中,通过对象VideoWriter。完成后调用VideoWriter.release()方法。

下面的这个程序会打开一个视频文件读取它的内容后将其转换为对数极坐标形式,然后将这种形式写入一个新的视频文件。

#include<opencv2/opencv.hpp>
#include<iostream>
int main(int argc, char** argv) {
	cv::namedWindow("test", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("log", cv::WINDOW_AUTOSIZE);
	cv::VideoCapture cap("灵梦.mp4");
	double fps = cap.get(cv::CAP_PROP_FPS);
	cv::Size size(
		(int)cap.get(cv::CAP_PROP_FRAME_WIDTH), (int)cap.get(cv::CAP_PROP_FRAME_HEIGHT)
	);
	cv::VideoWriter writer;
	writer.open("leimo.mp4", CV_FOURCC('M', 'J', 'P', 'G'), fps, size);
	cv::Mat log, bgr;
	for (;;) {
		cap >> bgr;
		if (bgr.empty())break;
		cv::imshow("test", bgr);
		cv::logPolar(bgr, log, cv::Point2f(bgr.cols / 2, bgr.rows / 2), 40, cv::WARP_FILL_OUTLIERS);
		cv::imshow("log", log);
		writer << log;
		char c = cv::waitKey(10);
		if (c == 27)break;
	}
	cap.release();
}

在这里插入图片描述---------------------------------------------------
参考:《学习OpenCV3》

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要安装opencv-contrib-python,您可以使用pip命令在命令行中运行以下命令: pip install opencv-contrib-python 这将自动下载和安装最新版本的opencv-contrib-python。请确保您的计算机已连接到互联网,并且您具有管理员权限。如果您遇到任何问题,请尝试使用管理员权限运行命令提示符。 ### 回答2: OpenCV是一款广泛应用于计算机视觉领域的开源库,支持多种编程语言(如C++、Python等)。OpenCV提供了大量的图像和视频处理函数和算法,包括但不限于图像的处理、特征提取、目标检测、人脸识别等功能。 而opencv-contrib-python则是OpenCV官方的扩展包,提供了更多的功能和算法。在使用Python进行图像处理和计算机视觉方面的应用时,opencv-contrib-python是非常重要的一个工具。 安装opencv-contrib-python要考虑多个方面,其中比较重要的两个方面是你所使用的Python版本和操作系统。具体的安装步骤如下: 1. 安装Python 访问Python官网或第三方Python发行版网站,在网站的页面中可以下载Python。根据自己的电脑操作系统和位数下载相应的版本,例如 Windows x64 Installer 这个exe文件即可。 2. 安装OpenCV 在Windows环境下可使用pip install opencv-contrib-python命令进行安装。另外需要注意的是,opencv-contrib-python命令默认会安装OpenCV 3.4.2版本,如果需要安装其他版本则需要加上版本号进行安装。如果没有pip可以去初步下载中默认下载的图形化界面Anaconda Navigator中寻找opencv-contrib-python,选择对应版本进行安装。 在Linux环境下可使用以下命令安装: sudo apt-get update sudo apt-get install python-opencv 3. 测试安装是否成功 打开Python编辑器,在其中输入import cv2即可,如果没有报错说明安装成功了。 总结,opencv-contrib-python在Python的图像处理和计算机视觉方面应用中不可缺少,通过上述安装步骤可以顺利安装并使用它。 ### 回答3: Opencv-contrib-python是Opencv的扩展库,其包含了Opencv官方没有包含的模块,例如SIFT算法等。它提供了方便的接口与脚本语言的接口,对于需要使用这些模块的Python开发者来说很有价值。 在安装opencv-contrib-python之前,需要先安装Opencv。如果已经安装好了Opencv的话,可以先在终端中输入 pip install opencv-contrib-python 来直接安装Opencv-contrib-python。如果还不确定是否安装好了Opencv,可以通过终端中输入下述命令进行确认: import cv2 print(cv2.__version__) 如果上述代码正确执行并输出Opencv的版本号,则表明Opencv已经成功安装。 如果使用的是Anaconda,则可以在终端直接使用命令 conda install opencv-contrib-python 进行安装。如果想要使用末版的opencv-contrib-python,则可以尝试以下代码: pip install opencv-contrib-python-headless 这些命令在安装过程中需要获取一些文件并安装一些依赖包。如果使用的是Python 3,需要确保下载安装的是Python 3.x版的Opencv-contrib-python,否则会出现错误。安装完成后,可以在Python中导入模块并调用其中的函数。 总体而言,Opencv-contrib-python安装比较简单,只需要保证已经正确安装了Opencv,并根据自己的需求选择安装相应的版本即可。安装过程中可能会遇到一些问题,但一般都可以在网络上找到解决方法。如果有更多的问题或者疑惑,在网络或者社区中提出问题是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值