1. 加载图像(cv::imread)

imread()功能是加载图像文件成为一个Mat对象,如果读取文件失败,则会返回一个空矩阵,即 Mat::data 的值是 NULL。imread()函数的声明如下:

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

其中第一个参数是表示图像文件名称;第二个参数表示加载的图像是什么类型,支持常见的三个参数值:

  • IMREAD_UNCHANGED(<0)表示加载原图,不做任何改变
  • IMREAD_GRAYSCALE(0)表示把原图作为灰度图像加载进来
  • IMREAD_COLOR(>0)表示把原图作为RGB图像加载进来

imread()函数支持多种文件格式,且该函数是根据图像文件的内容来确定文件格式,而不是根据文件的扩展名来确定。所只是的文件格式如下:

  • Windows 位图文件 - BMP, DIB;
  • JPEG 文件 - JPEG, JPG, JPE;
  • 便携式网络图片 - PNG;
  • 便携式图像格式 - PBM,PGM,PPM;
  • Sun rasters - SR,RAS;
  • TIFF 文件 - TIFF,TIF;
  • OpenEXR HDR 图片 - EXR;
  • JPEG 2000 图片- jp2。

你所安装的 OpenCV 并不一定能支持上述所有格式,文件格式的支持需要特定的库,只有在编译 OpenCV 添加了相应的文件格式库,才可支持其格式。

2. 显示图像(cv::nameWindows与cv::imshow)

  • namewindows功能是创建一个OpenCV窗口,它是由OpenCV自动创建与释放,你无须手动销毁它。
  • 常见用法 nameWindows("windowTitle", WINDOW_AUTOSIZE)
  • WINDOW_AUTOSIZE 会自动根据图像大小,显示窗口大小,不能认为改变窗口大小
  • WINDOW_NORMAL 跟QT集成的时候会使用,允许修改窗口大小
  • imshow 根据窗口名称显示图像到窗口上去,第一个参数是窗口名称,第二个参数是Mat对象

3. 修改图像(cv::cvtColor)

cvtColor的功能是把图像从一个色彩空间转换到另一个色彩空间。有三个参数如下:

第一个参数表示原图像

第二个参数表示色彩空间转换之后的图像

第三个参数表示转换方式,如:CV_BGR2GRAY、CV_BGR2HSV等

代码如下:

cvtColor(src, outputImage, CV_BGR2GRAY);

4. 保存图像(cv::imwrite)

将图像写入文件,可使用 imwrite()函数,该函数的声明如下:

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

文件的格式由 filename 参数指定的文件扩展名确定。推荐使用 PNG 文件格式。BMP 格式是无损格式,但是一般不进行压缩,文件尺寸非常大;JPEG 格式的文件娇小,但是 JPEG 是有损压缩,会丢失一些信息。PNG 是无损压缩格式,推荐使用。

imwrite()函数的第三个参数 params 可以指定文件格式的一些细节信息。这个参数里面的数值是跟文件格式相关的:

  • JPEG:表示图像的质量,取值范围从 0 到 100。数值越大表示图像质量越高,当然文件也越大。默认值是 95。
  • PNG:表示压缩级别,取值范围是从 0 到 9。数值越大表示文件越小,但是压缩花费的时间也越长。默认值是 3。
  • PPM,PGM 或 PBM:表示文件是以二进制还是纯文本方式存储,取值为0 或 1。如果取值为 1,则表示以二进制方式存储。默认值是 1。

并不是所有的 Mat 对象都可以存为图像文件,目前支持的格式只有 8U 类型的单通道和 3 通道(颜色顺序为 BGR)矩阵;如果需要要保存 16U 格式图像,只能使用 PNG、JPEG 2000 和 TIFF 格式。如果希望将其他格式的矩阵保存为图像文件,可以先用 Mat::convertTo()函数或者 cvtColor()函数将矩阵转为可以保存的格式。

注意:在保存文件时,如果文件已经存在,imwrite()函数不会进行 醒,将直接覆盖掉以前的文件。

5. 读视频

VideoCapture 既可以从视频文件读取图像,也可以从摄像头读取图像。可以使用该类的构造函数打开视频文件或者摄像头。如果 VideoCapture 对象已经创建,也可以使用 VideoCapture::open()打开,VideoCapture::open()函数会自动调用VideoCapture::release()函数,先释放已经打开的视频,然后再打开新视频。

VideoCapture cap(0);  //打开第一个摄像头
VideoCapture cap("filename.avi"); //打开视频文件

如果要读一帧,可以使用 VideoCapture::read()函数。VideoCapture 类重载了>>操作符,实现了读视频帧的功能。

#include <iostream>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main(int argc, char** argv)
{
VideoCapture cap(0); //打开第一个摄像头
if(!cap.isOpened()) { //检查是否成功打开
cerr << "Can not open a camera or file." << endl;
return -1;
}
Mat edges;
namedWindow("edges",1); //创建窗口
while(1) {
Mat frame;
cap >> frame; //从 cap 中读一帧,存到 frame
if(frame.empty()){ //如果未读到图像
break;
}
cvtColor(frame, edges, CV_BGR2GRAY); //将读到的图像转为灰度图
Canny(edges, edges, 50, 150, 3); //进行边缘 取操作
imshow("edges", edges); //显示结果
if(waitKey(30) >= 0) { //等待 30 秒,如果按键则推出循环
break;
}
}
//退出时会自动释放 cap 中占用资源
return 0;
}

6. 写视频

使用 OpenCV 创建视频也非常简单,与读视频不同的是,你需要在创建视频时设置一系列参数,包括:文件名,编解码器,帧率,宽度和高度等。编解码器使用四个字符表示,可以是 CV_FOURCC('M','J','P','G')、CV_FOURCC('X','V','I','D')及CV_FOURCC('D','I','V','X')等。如果使用某种编解码器无法创建视频文件,请尝试其他的编解码器。

将图像写入视频可以使用 VideoWriter::write()函数,VideoWriter 类中也重载了<<操作符,使用起来非常方便。另外需要注意:待写入的图像尺寸必须与创建视频时指定的尺寸一致。

#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
//定义视频的宽度和高度
Size s(320, 240);
//创建 writer,并指定 FOURCC 及 FPS 等参数
VideoWriter writer = VideoWriter("/Users/Longxia/Downloads/myvideo.avi", CV_FOURCC('M','J','P','G'), 25, s);
//检查是否成功创建
if(!writer.isOpened()) {
cerr << "Can not create video file.\n" << endl;
return -1;
}
//视频帧
Mat frame(s, CV_8UC3);
for(int i = 0; i < 100; i++)
{
//将图像置为黑色
frame = Scalar::all(0);
//将整数 i 转为 i 字符串类型
char text[128];
snprintf(text, sizeof(text), "%d", i);
//将数字绘到画面上
putText(frame, text, Point(s.width/3, s.height/3),
FONT_HERSHEY_SCRIPT_SIMPLEX, 3, Scalar(0,0,255), 3, 8);
//将图像写入视频
writer << frame;
}
//退出程序时会自动关闭视频文件
return 0;
}

7. imread()RGB的转换

方法转自:知乎

我们在使用OpenCV时,经常需要将处理过的图片展示出来,由于OpenCV中显示图片的函数cv2.imshow()功能往往不能满足我们的需求,所以经常用Matplotlib显示图像,方便结果图片的放大、保存等操作。

但是,OpenCV和Matplotlib中图片的像素排列方式略有不同。OpenCV中图片像素按照BGR(HWC)方式排列,而Matpoltlib中图片按照RGB方式排序,这样使用OpenCV读入的图片经过Matplotlib展示时,就会出现反相问题。

这里使用OpenCV的logo作为实验对象:

img = cv.imread("logo.png")#使用OpenCV读入图像
plt.subplot(111);plt.imshow(img);plt.title("Original")#使用matplotliob展示图片

与原图相比,上图的红色部分与蓝色部分交换了位置,意思是图片中红色像素和蓝色像素排列位置做了交换,印证了读入的BGR格式经过Matplotlib展示后变成了RGB格式。而且绿色的部分也有明显的色差。

要想正确的显示图片,必须先把读入的BGR图片中的B通道和R通道交换位置。这里有两种可行的方法可以实现BGR 2 RGB操作。

方法1:先拆分通道B、G、R,再合并通道R、G、B。

b,g,r = cv.split(img)#拆分通道
img_1 = cv.merge([r,g,b])#合并通道

在拆分通道时,除了使用OpenCV的split()方法,还可以用Numpy的索引:

b = image[:,:,0]#得到蓝色通道
g = image[:,:,1]#得到绿色通道
r = image[:,:,2]#得到红色通道

在Matplotlib中显示:

plt.subplot(111);plt.imshow(img);plt.title("Original")
plt.subplot(122);plt.imshow(img_1);plt.title("Display_RGB")



在第二幅图片中,可以看到展示结果与原图一致。

方法2:直接使用Numpy索引

我们都知道Numpy在计算这种大型矩阵时,索引的效率很高,所以下面的方法简单高效,及其推荐使用。

img_2 = img[:,:,::-1]
plt.subplot(131);plt.imshow(img);plt.title("Original")
plt.subplot(132);plt.imshow(img_1);plt.title("Display_RGB")
plt.subplot(133);plt.imshow(img_2);plt.title("Display_RGB")
plt.show()

也可以

img = cv2.imread(fengmian)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2默认为bgr顺序

8. 图像的膨胀(dilate)和腐蚀(erode)

详细说明

需要注意,腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,“领域被蚕食”,效果图拥有比原图更小的高亮区域。

[OpenCV]OpenCV常用语法函数与坑点的更多相关文章

  1. OpenCV计算机视觉学习(1)——图像基本操作(图像视频读取,ROI区域截取,常用cv函数解释)

    1,计算机眼中的图像 我们打开经典的 Lena图片,看看计算机是如何看待图片的: 我们点击图中的一个小格子,发现计算机会将其分为R,G,B三种通道.每个通道分别由一堆0~256之间的数字组成,那Ope ...

  2. OpenCV中的绘图函数-OpenCV步步精深

    OpenCV 中的绘图函数 画线 首先要为画的线创造出环境,就要生成一个空的黑底图像 img=np.zeros((512,512,3), np.uint8) 这是黑色的底,我们的画布,我把窗口名叫做i ...

  3. OpenCV混合高斯模型函数注释说明

    OpenCV混合高斯模型函数注释说明 一.cvaux.h #define CV_BGFG_MOG_MAX_NGAUSSIANS 500 //高斯背景检测算法的默认参数设置 #define CV_BGF ...

  4. 【opencv基础】detectmultiscale函数详解

    前言 简单的人脸检测程序可以直接基于opencv的函数库进行实现,本文介绍一下detectMultiScale函数. 函数简介 opencv2人脸检测使用的是detectMultiScale函数,可以 ...

  5. 基础常用JS函数和语法

    100多个基础常用JS函数和语法集合大全  来源:http://www.cnblogs.com/hnyei/p/4605103.html 网站特效离不开脚本,javascript是最常用的脚本语言,我 ...

  6. 基础学习笔记之opencv(24):imwrite函数的使用

    http://www.cnblogs.com/tornadomeet/archive/2012/12/26/2834336.html 前言 OpenCV中保存图片的函数在c++版本中变成了imwrit ...

  7. 超越OpenCV速度的MorphologyEx函数实现(特别是对于二值图,速度是CV的4倍左右)。

    最近研究了一下opencv的 MorphologyEx这个函数的替代功能, 他主要的特点是支持任意形状的腐蚀膨胀,对于灰度图,速度基本和CV的一致,但是 CV没有针对二值图做特殊处理,因此,这个函数对 ...

  8. api日常总结:前端常用js函数和CSS常用技巧

    我的移动端media html{font-size:10px} @media screen and (min-width:321px) and (max-width:375px){html{font- ...

  9. oracle(sql)基础篇系列(一)——基础select语句、常用sql函数、组函数、分组函数

        花点时间整理下sql基础,温故而知新.文章的demo来自oracle自带的dept,emp,salgrade三张表.解锁scott用户,使用scott用户登录就可以看到自带的表. #使用ora ...

随机推荐

  1. The Personal Touch Client Identification 个性化接触 客户识别

    w服务器要知道和谁在交谈. HTTP The Definitive Guide Web servers may talk to thousands of different clients simul ...

  2. Logstash利用GeoIP库显示地图以及通过useragent显示浏览器(

    http://www.nibayuan.com/articles/2016/02/23/elk-logstash-geoip-kibana-tilemap.html 我们通过Logstash收集的Ng ...

  3. Android Studio升级后报 method not found: 'runProguard'的错误

    今天升级了下Android Studio,然后发现更新gradle,然后在sync项目的时候总是报  method not found: 'runProguard'的错误 找了很多发现不对. 最后解决 ...

  4. linux创建lvm分区

    创建LVM分区 shell> fdisk /dev/xvdb #### 选择磁盘 Command (m for help): m #### 帮助 Command action a toggle ...

  5. openresty环境搭建问题记录

    第一次在mac安装遇到如下问题: 截图: 具体code如下: Sonofelice:bch-flowrouter baidu$ brew install openresty/brew/openrest ...

  6. IDEA中打包Spark项目提示Error:(16, 48) java: -source 1.5 中不支持 lambda 表达式

    在idea中新建了一Spark的项目,在做项目的编译打包的时候,提示如下错误信息: Error:(, ) java: -source 1.5 中不支持 lambda 表达式 (请使用 -source ...

  7. Intellij IDEA如何使用Maven Tomcat Plugin运行web项目

    首先,Run ——> Edit Configurations,这时候如下图: 然后点击左上角的加号,可以添加一个新的配置,如下图: 选择Maven,如下图: 下面填上自己的配置信息,点击appl ...

  8. RF的优缺点

    随机森林有什么优点,如: a. 对于很多数据集表现良好,精确度比较高: b. 不容易过拟合: c. 可以得到变量的重要性排序: d. 既能处理离散型数据,也能处理连续型数据,且不需要进行归一化处理: ...

  9. python全栈开发从入门到放弃之面向对象反射

    1.classmethod.staticmethod方法 classmethod类方法默认参数cls,可以直接用类名调用,可以与类属性交互 #student文件内容 宝宝,男 博博,女 海娇,男 海燕 ...

  10. yii2 中where条件查询

    在Yii的Model里进行查询的时候 where是必不可少的. Where方法声明为 static where( $condition ) 其中参数 $condition 类型为字符串或者数组1.字符 ...