(注:确保cuda版本为9.0,确保FFmpeg已安装)
#必要的依赖项
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
#源码
git clone https://github.com/opencv/opencv.git
#git clone https://github.com/opencv/opencv_contrib.git
#编译
cd opencv
mkdir build
cd build
#Run cmake []
#注意:如果`cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..`不起作用,请在-D后使用空格
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j12
sudo make install
opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。而CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。
Mat是opencv2.0推出的处理图像的新的数据结构,现在越来越有趋势取代之前的cvMat和lplImage,相比之下Mat最大的好处就是能够更加方便的进行内存管理,不再需要程序员手动管理内存的释放。
opencv2.3中提到Mat是一个多维的密集数据数组,可以用来处理向量和矩阵、图像、直方图等等常见的多维数据。
OpenCV 将颜色读取为 BGR(蓝绿色红色),但大多数计算机应用程序读取为 RGB(红绿蓝)
#include
using namespace cv;
Mat image =imread("*.jpg", [ImreadModes]); //读取一个jpg文件到image对象中
Mat( int rows, int cols, int type ); //指定行、列、类型、(初始化数据)
注:[ImreadModes]
enum ImreadModes {
IMREAD_UNCHANGED = -1, //不进行转化,比如保存为了16位的图片,读取出来仍然为16位。(载入源图像,并添加alpha通道)
IMREAD_GRAYSCALE = 0, //进行转化为灰度图,比如保存为了16位的图片,读取出来为8位,类型为CV_8UC1。(Y=0.3R+0.59G+0.11B)
IMREAD_COLOR = 1, //进行转化为三通道彩色图像。
IMREAD_ANYDEPTH = 2, //如果图像深度为16位则读出为16位,32位则读出为32位,其余的转化为8位。读取任意深度的图片
IMREAD_ANYCOLOR = 4, //如果设置了,那么就载入任意可能的颜色格式而不进行转换. (常用)
IMREAD_LOAD_GDAL = 8, //使用GDAL驱动读取文件,GDAL是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。
IMREAD_REDUCED_GRAYSCALE_2 = 16, //图像总是转换为单通道灰度图,且尺寸缩减为1/2
IMREAD_REDUCED_COLOR_2 = 17, //图像总是转换为彩色3通道BGR且尺寸缩减为1/2.
IMREAD_REDUCED_GRAYSCALE_4 = 32, //同上,灰度,缩减为1/4.
IMREAD_REDUCED_COLOR_4 = 33, //同上,彩色,缩减为1/4.
IMREAD_REDUCED_GRAYSCALE_8 = 64, //同上,灰度,缩减为1/8.
IMREAD_REDUCED_COLOR_8 = 65, //同上,彩色,缩减为1/8.
IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
};
image.cols; //矩阵的列数,例:1920
image.rows; //矩阵的行数,例:1080
image.data; //指向矩阵的数据单元的指针
image.size; //矩阵大小,例:1080 x 1920
image.flags; //0-11位共同代表type即通道数和数据类型,14位代表Mat的内存是否连续
image.channels(); //通道数
image.step[0~1]; //setp[0]: 线的数据量大小,单位为字节。setp[1]: 点的数据量大小(step[i]是Mat类中十分重要的一个属性,表示第i维的总大小,单位字节)
image.empty(); //判断是否为空
namedWindow(vod_id, CV_WINDOW_NORMAL); //CV_WINDOW_NORMAL窗口可调整,默认WINDOW_AUTOSIZE
imshow("name", image);
resizeWindow(vod_id, 1920, 1080);
waitKey(3*1000);//显示需要延时ms,等待用户按任意键
destroyWindow("name");
destroyAllWindows();
引申:判断窗口是否还在(cvGetWindowHandle("name"))
Mat image2; //定义一个新mat对象
resize(image, image2, Size(30,30)); //调整目标大小为30*30
调整矩阵维度:Mat::reshape(int cn, int rows=0)
cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数。
rows: 表示矩阵行数。 如果设为0,则表示保持原有的行数不变,否则则变为设置的行数。
std::vector data_encode; //用于保存编码后的数据流
vector param = vector(2);
param[0]=CV_IMWRITE_JPEG_QUALITY;
param[1]=95;//default(95) 0-100
imencode(".png", image, data_encode, param); //编码为png格式,image:Mat格式,data_encode:vector格式
Mat img_decode; //定义一个新mat对象,用于保存解码后的数据
img_decode = imdecode(data_encode, [ImreadModes]); //data_encode:可以是Mat格式,也可以是vector格式
vector encode_param= vector(2);
encode_param[0]=IMWRITE_JPEG_QUALITY;
encode_param[1]=Cr; //压缩比:default(95) 0-100
imwrite(“*.jpg”, img_decode, endoe_param); //保存为jpg格式图像,encode_param为保存参数。
注:[ImwriteFlags]
enum ImwriteFlags {
IMWRITE_JPEG_QUALITY = 1, //For JPEG,它可以是从0到100的质量(越高越好),默认值95。
IMWRITE_JPEG_PROGRESSIVE = 2, //启用jpeg功能(进步的),0或1,默认值为false。
IMWRITE_JPEG_OPTIMIZE = 3, //启用jpeg功能(最优化),0或1,默认值为false。
IMWRITE_JPEG_RST_INTERVAL = 4, //!< JPEG restart interval, 0 - 65535, default is 0 - no restart.——jpeg重新启动间隔
IMWRITE_JPEG_LUMA_QUALITY = 5, //!< Separate luma quality level, 0 - 100, default is 0 - don't use.——分离腔质量水平
IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is 0 - don't use.——分离色度质量水平
//对于PNG,它可以是0到9之间的压缩级别。较高的值意味着较小的大小和较长的压缩时间。如果指定,策略将更改为IMWRITE_png_strategy_default(z_default_strategy)。默认值为1(最佳速度设置)。
IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. If specified, strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY). Default value is 1 (best speed setting).
IMWRITE_PNG_STRATEGY = 17, //!< One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE
enum ImwritePNGFlags {
IMWRITE_PNG_STRATEGY_DEFAULT = 0, //!< Use this value for normal data.
IMWRITE_PNG_STRATEGY_FILTERED = 1, //!< Use this value for data produced by a filter (or predictor).Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better.——对于由过滤器(或预测器)生成的数据,使用该值。过滤后的数据主要由具有某种随机分布的小值组成。在这种情况下,将调整压缩算法以更好地压缩它们。
IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY = 2, //!< Use this value to force Huffman encoding only (no string match).——使用此值仅强制哈夫曼编码(无字符串匹配)
IMWRITE_PNG_STRATEGY_RLE = 3, //!< Use this value to limit match distances to one (run-length encoding).——使用此值将匹配距离限制为一(运行长度编码)。
IMWRITE_PNG_STRATEGY_FIXED = 4 //!< Using this value prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.——使用该值可防止使用动态哈夫曼码,从而为特殊应用提供更简单的解码器。
};
IMWRITE_PNG_BILEVEL = 18, //!< Binary level PNG, 0 or 1, default is 0.——二进制级别png,0或1,默认值为0。
IMWRITE_PXM_BINARY = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1.——对于PPM、PGM或PBM,它可以是二进制格式标志0或1。默认值为1。
IMWRITE_EXR_TYPE = (3 << 4) + 0, /* 48 */ //!< override EXR storage type (FLOAT (FP32) is default)
IMWRITE_WEBP_QUALITY = 64, //!< For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used.
IMWRITE_PAM_TUPLETYPE = 128,//!< For PAM, sets the TUPLETYPE field to the corresponding string value that is defined for the format
IMWRITE_TIFF_RESUNIT = 256,//!< For TIFF, use to specify which DPI resolution unit to set; see libtiff documentation for valid values
IMWRITE_TIFF_XDPI = 257,//!< For TIFF, use to specify the X direction DPI
IMWRITE_TIFF_YDPI = 258 //!< For TIFF, use to specify the Y direction DPI
};
std::vector channels;
Mat aChannels[3];
split(src, aChannels); //利用数组分离 //src为要分离的Mat对象
split(src, channels); //利用vector对象分离
//注意:opencv中,RGB三个通道是反过来的 //可能有人会问为什么分离出的通道都是黑白灰,而不是红绿蓝。原因是分离后为单通道,相当于分离通道的同时把其他两个通道填充了相同的数值。
imshow("B",channels[0]);
imshow("G",channels[1]);
imshow("R",channels[2]);
引申:合并图像通道(merge())
CV_8UC1:是指一个8位无符号整型单通道矩阵。
CV_32FC2:是指一个32位浮点型双通道矩阵。
CV_8UC1 CV_8SC1 CV_16UC1 CV_16SC1
CV_8UC2 CV_8SC2 CV_16UC2 CV_16SC2
CV_8UC3 CV_8SC3 CV_16UC3 CV_16SC3
CV_8UC4 CV_8SC4 CV_16UC4 CV_16SC4
CV_32SC1 CV_32FC1 CV_64FC1
CV_32SC2 CV_32FC2 CV_64FC2
CV_32SC3 CV_32FC3 CV_64FC3
CV_32SC4 CV_32FC4 CV_64FC4
Mat::convertTo(MatTemp2, CV_8U) //拷贝 //把矩阵matTemp转为unsing char类型的矩阵,注在转换过程中有可能数值上会出现一些变化,这个要注意
Mat img_copy = img.clone(); //将img拷贝到img_copy
img_copy.at(14,25) = 25; //8U类型的RGB彩色图像可以使用,3通道float类型的矩阵可以使用
bool cv::Mat::isContinuous() const //如果矩阵元素在每行末尾连续存储而没有间隙,则方法返回true。 否则,它返回false。 显然,对于1x1或1xN矩阵总是连续的。一般 用Mat :: create创建的矩阵总是连续的。 但是,如果使用Mat :: col,Mat :: diag等提取矩阵的一部分,或者为外部分配的数据构造矩阵头,则此类矩阵可能不再具有此属性。
float *p = image.ptr(0); //返回一个指针指向image第一行第一个元素。mat.ptr<...>(1)为第2行第一个元素;mat.ptr<...>(0)[1]为第一行第2个元素。
Mat A=testMat(Rect(0,1,1,2)); //函数Rect的第一个参数为起始的列,第二个参数为起始的行,第三个参数为子矩阵的列数,第四个参数为子矩阵的行数。
VideoCapture::VideoCapture()
VideoCapture::VideoCapture(const string& filename) //filename – 打开的视频文件名
VideoCapture::VideoCapture(int device) //device – 打开的视频捕获设备id ,如果只有一个摄像头可以填0,表示打开默认的摄像头。
VideoCapture::open(const string& filename) //filename – 打开的视频文件。例:
capture.open("rtsp://admin:[email protected]:554/cam/realmonitor?channel=1&subtype=0", CAP_FFMPEG);
capture.open("/home/toson/example-content/Ubuntu_Free_Culture_Showcase/Nathan Haines - Ubuntu Through The Years.ogg");
VideoCapture::open(int device) //device – 打开的视频捕获设备id ,如果只有一个摄像头可以填0,表示打开默认的摄像头。
cv2.VideoCapture.get(0) 视频文件的当前位置(播放)以毫秒为单位
cv2.VideoCapture.get(1) 基于以0开始的被捕获或解码的帧索引(当前帧数)
cv2.VideoCapture.get(2) 视频文件的相对位置(播放):0=电影开始,1=影片的结尾。
cv2.VideoCapture.get(3) 在视频流的帧的宽度
cv2.VideoCapture.get(4) 在视频流的帧的高度
cv2.VideoCapture.get(5) 帧速率
cv2.VideoCapture.get(6) 编解码的4字-字符代码
cv2.VideoCapture.get(7) 视频文件中的帧数(总帧数)
cv2.VideoCapture.get(8) 返回对象的格式
cv2.VideoCapture.get(9) 返回后端特定的值,该值指示当前捕获模式
cv2.VideoCapture.get(10) 图像的亮度(仅适用于照相机)
cv2.VideoCapture.get(11) 图像的对比度(仅适用于照相机)
cv2.VideoCapture.get(12) 图像的饱和度(仅适用于照相机)
cv2.VideoCapture.get(13) 色调图像(仅适用于照相机)
cv2.VideoCapture.get(14) 图像增益(仅适用于照相机)(Gain在摄影中表示白平衡提升)
cv2.VideoCapture.get(15) 曝光(仅适用于照相机)
cv2.VideoCapture.get(16) 指示是否应将图像转换为RGB布尔标志
cv2.VideoCapture.get(17) × 暂时不支持
cv2.VideoCapture.get(18) 立体摄像机的矫正标注(目前只有DC1394 v.2.x后端支持这个功能)
Mat frame; //当前视频帧
capture.read(frame);
capture >> frame;
cv2.VideoCapture.set(CV_CAP_PROP_POS_FRAMES, 10) //基于以0开始的被捕获或解码的帧索引(当前帧数)
//
// Created by toson on 19-2-22.
//
#include "common.h"
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
/*********************************************
名称:image_resize
功能:图片大小压缩
输入:
filename: 文件路径名
size_cols: 输出文件列像素值(列)
size_rows:输出文件行像素值(行)
返回值:
true 成功
false 失败
*********************************************/
int image_resize(string filename, int size_cols, int size_rows) {
try {
cout << "img_resize test." << endl;
//读取图片
Mat img = imread(filename);
//显示图片
//imshow("she_img_0", img);
//waitKey(100 * 1000);
//pause();//system("pause");
//压缩图片大小
resize(img, img, Size(size_cols, size_rows), 0, 0, CV_INTER_LINEAR);
//显示压缩后的图片
// imshow("she_img_1_resize", img);
// waitKey(100 * 1000);
//保存压缩后的图片
filename.insert(filename.find_last_of('.'), "_resize_"+ to_string(size_cols) + "_" + to_string(size_rows));
cout << "Save as " << filename << endl;
imwrite(filename, img);
}
catch (exception &e) {
cout << e.what() << endl;
return false;
}
return true;
}
/*********************************************
名称:image_encode
功能:图片编码压缩
输入:
filename:文件路径名
file_ext: 输出文件格式
Cr: 压缩比:default(95) 0-100
返回值:
true 成功
false 失败
*********************************************/
bool image_encode(string filename, const String file_ext, const int Cr = 95)
{
try{
//read a image
Mat img = imread(filename);
//display the image
// imshow("img_0", img);
// waitKey(10 * 1000);
// destroyWindow("simg_0");
//the image stream size
vector img_data;
imencode(".bmp", img, img_data);
cout << "The image stream size(bmp): " << img_data.size() << endl;
//data stream to mat image
Mat image = imdecode(img_data, CV_LOAD_IMAGE_COLOR);
// cout << "imshow stream image" << endl;
// imshow("stream image", image);
// waitKey(10 * 1000);
// destroyWindow("stream image");
//set encode parameter
vector encode_param= vector(2);
encode_param[0]=CV_IMWRITE_JPEG_QUALITY;
encode_param[1]=Cr;//default(95) 0-100
//start encode the image
vector encoded_data;//buffer for coding
imencode(file_ext, image, encoded_data, encode_param);
cout<<"image size(" << file_ext << "): "<