opencv2库
1. opencv2库
1.1 opencv2库下载
2. 编译和部署
OpenCV 数据结构
基本数据结构
对于单通道图像,Mat.at(i,j)表示第i行j列的像素值
对于多通道图像,如RGB图像,Mat.at(i,j)[c],[c]表示某个通道在(i,j)位置的像素值。c取0就是B分量,取1就是G分量,取2就是R分量。
32 表示单精度
64 表示双精度
F 表示浮点
U 表示无符号
S 表示有符号
Cx 表示通道数,如RGB三通道
//矩阵类型 数据类型
CV_8U Mat.at<uchar>(y,x) 表示8位无符号整数(0…255)
CV_8S Mat.at<schar>(y,x) 表示8位有符号整数(-128…127)
CV_16U Mat.at<ushort>(y,x) 表示16位无符号整数(0…65535)
CV_16S Mat.at<short>(y,x) 表示16位有符号整数(-32768…32767)
CV_32S Mat.at<int>(y,x) 表示32位有符号整数(-2147483648…2147483647)
CV_32F Mat.at<float>(y,x) 表示32位浮点数
CV_64F Mat.at<double>(y,x) 表示64位浮点数
图像类型
CV_8UC1
CV_8UC3
CV_32FC3
CV_8UC1转化为CV_8UC3
Mat dst;
Mat src(height, width, CV_8UC1, (unsigned char*) captureClient->data());
//法一
src.convertTo(dst, CV_8UC3);
//法二:该图像与灰度CV_8UC1时的外观相同,但它将是类型为CV_8UC3的3通道图像。
cvtColor(src, dst, COLOR_GRAY2RGB);
API
cv::imread 与 cv::imwrite
cv::imread 读图像列表
//官方API
cv::Mat imread( const String& filename, int flags = IMREAD_COLOR);
//示例
std::string file_path= "D:\work";
//示例一
cv::Mat image = cv::imread(file_path + "\\" + file_name);
//示例二
cv::Mat image = cv::imread(file_path + "/depth.tiff", cv::IMREAD_UNCHANGED);
cv::imwrite写图像
//官方API
bool imwrite( const String& filename, InputArray img,
const std::vector<int>& params = std::vector<int>());
//示例
std::string file_path= "D:\work";
cv::Mat image;
cv::imwrite(file_path+ "/image.bmp", image);
//深度图,tiff 格式
std::vector<int> compression;
compression.push_back(cv::IMWRITE_TIFF_COMPRESSION);
compression.push_back(0);
cv::imwrite("C:/Users/Desktop/123123/image_depth1.tiff", image_depth);
cv::imwrite("C:/Users/Desktop/123123/image_depth1.tiff", image_depth, compression);
示例接口
bool WriteImagelist(const std::string file_path, std::vector<cv::Mat> image_list) {
for (unsigned int i = 0; i < image_list.size(); i++) {
if (!cv::imwrite(file_path + "/image" + std::to_string(i) + ".bmp", image_list[i])) {
return false;
}
}
return true;
}
cv::imshow
cv::imshow("display title", image);
cv::waitKey(500);
cv::destroyWindow("display title");
cv::FileStorage
//读 json 文件
bool ReadSaveFile(cv::Mat& test_max, double& test_double) {
std::string file_path = "D:/work";
cv::FileStorage fs(file_path + "/test.json", cv::FileStorage::WRITE);
fs["Mat"] >> test_max;
fs["double"] >> test_double;
fs.release();
return true;
}
//写 json 文件
bool SaveFile() {
//数据示例
cv::Mat test_max;
double test_double = 0.008;
std::string file_path = "D:/work";
cv::FileStorage fs(file_path + "/test.json", cv::FileStorage::WRITE);
fs << "Mat" << test_max;
fs << "double" <<test_double;
fs.release();
return true;
}
cv::merge 与 cv::split
在图像处理中,有时需要对各个通道进行分离,分别处理;或者进行通道合并。
cv::split()用于实现图像通道的分离。
cv::Mat image;
cv::split(src,channels);
cv::Mat channel_red = channels.at(2);
cv::Mat channel_green = channels.at(1);
cv::Mat channel_blue = channels.at(0);
cv::merge()用于实现图像通道的合并,是split的逆向操作。
cv::Mat image;
std::vector<cv::Mat> channels;
cv::merge(channels, image);
附录一:获取文件夹下文件
//获取文件夹路径
#include <QFileDialog>
QString filePath = QFileDialog::getExistingDirectory(this, tr("Selet Path"), "./");
对比方法一和方法二 | |||||||||
方法一 | 能够输出每一个文件的名称,且只识别图像格式的文件,其他文件会被过滤。 | ||||||||
方法二 | 更加简单,不过文件夹下只能有图片格式的文件,否则存在隐患。 |
- 使用QT QFileDialog
#include <QFileDialog>
bool ReadImagelist(const QString file_path, std::vector<cv::Mat> image_list) {
QDir dir(file_path);
QStringList image_type_list;
image_type_list << "*.bmp" << "*.jpg" << "*.png";//向字符串列表添加图片类型
dir.setNameFilters(image_type_list); //获得文件夹下图片的名字
int ImageCount = dir.count(); //获得dir里名字的个数,也表示文件夹下图片的个数
for (int i=0;i < ImageCount; i++)
{
cv::Mat image = cv::imread((file_path + "\\" + dir[i]).toStdString());
qDebug() << QString::number(222) + ": " + file_path + dir[i];//输出图片名
image_list.push_back(image);
}
return true;
}
- 使用CV库
bool ReadImagelist(const std::string file_path, std::vector<cv::Mat> image_list) {
std::vector<std::string> file_name;
cv::glob(file_path, file_name, false);
for (int i = 0; i < file_name.size(); i++)
{
cv::Mat image = cv::imread(file_name[i]);
qDebug() << QString::number(111) + ": " + QString::fromStdString(file_name[i]);
image_list.push_back(image);
}
return true;
}