Mat lookUpTable(1,256,CV_8U);
u从三个都说副高fdffffDdqqqdqddq FQFQ2Q2W GW 问对方成为亲卫队请问我去问驱蚊器委屈委屈强强
char* p = lookUpTable.data;
for(int i = 0 ; i < 256 ; ++i)
p[i] = table[i];
//然后调用函数(I是输入 J是输出):
for (int i = 0; i < times; ++i)
LUT(I, lookUpTable, J);
getTickCount()返回CPU自某个事件以来走过的时钟周期数
getTickFrequency()返回CPU一秒钟所走的时钟周期数
double time0 = static_cast<double>(getTickCount());//记录起始时间
//进行图像处理操作。。。。。
time0 = ((double)getTickCount() - time0)/getTickFrequency();
cout<<"此方法运行事件:"<<time0<<"秒"<<endl;//输出运行时间
方法一 指针访问:C操作符[];
方法二 迭代器iterator
方法三 动态地址计算
#include
#include
#include
using namespace std;
using namespace cv;
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
int main()
{
//【1】创建原始图并显示
Mat srcImage = imread("1.bmp",1);
imshow("原始图像", srcImage);
//【2】按原始图的参数规格来创建创建效果图
Mat dstImage;
dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同
//【3】记录起始时间
double time0 = static_cast<double>(getTickCount());
//【4】调用颜色空间缩减函数
colorReduce(srcImage, dstImage, 32);
//【5】计算运行时间并输出
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "\t此方法运行时间为: " << time0 << "秒" << endl; //输出运行时间
//【6】显示效果图
imshow("效果图", dstImage);
waitKey(0);
}
//---------------------------------【colorReduce( )函数】---------------------------------
// 描述:使用【指针访问:C操作符[ ]】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
//参数准备
outputImage = inputImage.clone(); //拷贝实参到临时变量
int rowNumber = outputImage.rows; //行数
int colNumber = outputImage.cols * outputImage.channels(); //列数 x 通道数=每一行元素的个数
//双重循环,遍历所有的像素值
for (int i = 0; i < rowNumber; i++) //行循环
{
uchar* data = outputImage.ptr<uchar>(i); //获取第i行的首地址
for (int j = 0; j < colNumber; j++) //列循环
{
// ---------【开始处理每个像素】-------------
data[j] = data[j] / div * div + div / 2;
//*data++ = *data / div * div + div / 2;//也可以写成这样
// ----------【处理结束】---------------------
} //行处理结束
}
}
//-------------------------------------【colorReduce( )函数】-----------------------------
// 描述:使用【迭代器】方法版的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
//参数准备
outputImage = inputImage.clone(); //拷贝实参到临时变量
//获取迭代器
Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>(); //初始位置的迭代器
Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>(); //终止位置的迭代器
//存取彩色图像像素
for(;it != itend;++it)
{
// ------------------------【开始处理每个像素】--------------------
(*it)[0] = (*it)[0]/div*div + div/2;
(*it)[1] = (*it)[1]/div*div + div/2;
(*it)[2] = (*it)[2]/div*div + div/2;
// ------------------------【处理结束】----------------------------
}
}
//----------------------------------【colorReduce( )函数】-------------------------------
// 描述:使用【动态地址运算配合at】方法版本的颜色空间缩减函数
//----------------------------------------------------------------------------------------------
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
//参数准备
outputImage = inputImage.clone(); //拷贝实参到临时变量
int rowNumber = outputImage.rows; //行数
int colNumber = outputImage.cols; //列数
//存取彩色图像像素
for(int i = 0;i < rowNumber;i++)
{
for(int j = 0;j < colNumber;j++)
{
// ------------------------【开始处理每个像素】--------------------
outputImage.at<Vec3b>(i,j)[0] = outputImage.at<Vec3b>(i,j)[0]/div*div + div/2; //蓝色通道
outputImage.at<Vec3b>(i,j)[1] = outputImage.at<Vec3b>(i,j)[1]/div*div + div/2; //绿色通道
outputImage.at<Vec3b>(i,j)[2] = outputImage.at<Vec3b>(i,j)[2]/div*div + div/2; //红是通道
// -------------------------【处理结束】----------------------------
} // 行处理结束
}
}
``
## 4.ROI(region of interest):感兴趣区域
```cpp
Mat imageROI;
//方法一
imageROI = srcImage(Rect(200, 250, logoImage.cols, logoImage.rows));
//方法二
//imageROI= srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));
通道分离:split函数
通道合并:merge函数
vector<Mat> channels;
split(srcImage, channels);//分离色彩通道
Mat imageBlueChannel = channels.at(0);
Mat imageGreenChannel = channels.at(1);
Mat imageRedChannel = channels.at(2);
merge(channels, srcImage);//将三个单通道重新合并成一个三通道
#include
#include
#include "opencv2/imgproc/imgproc.hpp"
#include
using namespace std;
using namespace cv;
static void ContrastAndBright(int, void*);
int g_nContrastValue; //对比度值
int g_nBrightValue; //亮度值
Mat g_srcImage, g_dstImage;
int main()
{
//改变控制台前景色和背景色
system("color 2F");
// 读入用户提供的图像
g_srcImage = imread("1.bmp");
if (!g_srcImage.data) { printf("读取g_srcImage图片错误~! \n"); return false; }
g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());
//设定对比度和亮度的初值
g_nContrastValue = 80;
g_nBrightValue = 80;
//创建窗口
namedWindow("【效果图窗口】", 1);
//创建轨迹条
createTrackbar("对比度:", "【效果图窗口】", &g_nContrastValue, 300, ContrastAndBright);
createTrackbar("亮 度:", "【效果图窗口】", &g_nBrightValue, 200, ContrastAndBright);
//调用回调函数
ContrastAndBright(g_nContrastValue, 0);
ContrastAndBright(g_nBrightValue, 0);
//输出一些帮助信息
cout << endl << "\t运行成功,请调整滚动条观察图像效果\n\n"
<< "\t按下“q”键时,程序退出\n";
//按下“q”键时,程序退出
while (char(waitKey(1)) != 'q') {}
return 0;
}
//-----------------------------【ContrastAndBright( )函数】------------------------------------
// 描述:改变图像对比度和亮度值的回调函数
//-----------------------------------------------------------------------------------------------
static void ContrastAndBright(int, void*)
{
// 创建窗口
namedWindow("【原始图窗口】", 1);
// 三个for循环,执行运算 g_dstImage(i,j) = a*g_srcImage(i,j) + b
for (int y = 0; y < g_srcImage.rows; y++)
{
for (int x = 0; x < g_srcImage.cols; x++)
{
for (int c = 0; c < 3; c++)
{
g_dstImage.at<Vec3b>(y, x)[c] = saturate_cast<uchar>((g_nContrastValue * 0.01) * (g_srcImage.at<Vec3b>(y, x)[c]) + g_nBrightValue);
}
}
}
// 显示图像
imshow("【原始图窗口】", g_srcImage);
imshow("【效果图窗口】", g_dstImage);
}
void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0)//第一个参数为输入矩阵;第二个参数为运算结果;第三个参数为转换的标识符(下表);第四个参数为想要处理的那一行值,函数会假设只有输入矩阵的第一个非零行包含非零元素。
int getOptimalDFTSize(int vecsize)//返回给定向量尺寸的DFT最优尺寸大小
void copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar&value=Scalar() )
//扩充图像边界
//第一个参数为输入图像;第二个参数为输出图像;第三到第六个参数:需要在四个方向边界扩充的像素数;第七个参数为边界类型,常用为BORDER_CONSTANT;第八个参数为const Scalar&类型的value,有默认值Scalar()。
void magnitude(InputArray x,InputArray y,OutputArray magnitude)
//计算二维矢量的幅值
//第一个参数为浮点型X坐标值,实部;第二个参数为浮点型Y坐标值,虚部;第三个参数为输出的幅值
//X和Y的平方和再开根号
void log(InputArray src, OutputArray dst)
//计算自然对数
void normalize(InputArray src, OutputArray dst, double alpha=1,double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask =noArray())
//矩阵归一化
//第一个参数为输入图像;第二个参数为输出图像;第三个参数为归一化后的最大值,第四个参数为归一化后的最小值;第五个参数为归一化类型;第六个参数取负值时,输出矩阵和src有同样的类型,否则有同样的通道数;第七个参数为可选的操作掩膜。
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include
using namespace cv;
int main()
{
//【1】以灰度模式读取原始图像并显示
Mat srcImage = imread("1.bmp", 0);
if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); return false; }
imshow("原始图像", srcImage);
//【2】将输入图像延扩到最佳的尺寸,边界用0补充
int m = getOptimalDFTSize(srcImage.rows);
int n = getOptimalDFTSize(srcImage.cols);
//将添加的像素初始化为0.
Mat padded;
copyMakeBorder(srcImage, padded, 0, m - srcImage.rows, 0, n - srcImage.cols, BORDER_CONSTANT, Scalar::all(0));
//【3】为傅立叶变换的结果(实部和虚部)分配存储空间。
//将planes数组组合合并成一个多通道的数组complexI
Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
Mat complexI;
merge(planes, 2, complexI);
//【4】进行就地离散傅里叶变换
dft(complexI, complexI);
//【5】将复数转换为幅值,即=> log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
split(complexI, planes); // 将多通道数组complexI分离成几个单通道数组,planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
Mat magnitudeImage = planes[0];
//【6】进行对数尺度(logarithmic scale)缩放
magnitudeImage += Scalar::all(1);
log(magnitudeImage, magnitudeImage);//求自然对数
//【7】剪切和重分布幅度图象限
//若有奇数行或奇数列,进行频谱裁剪
magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));
//重新排列傅立叶图像中的象限,使得原点位于图像中心
int cx = magnitudeImage.cols / 2;
int cy = magnitudeImage.rows / 2;
Mat q0(magnitudeImage, Rect(0, 0, cx, cy)); // ROI区域的左上
Mat q1(magnitudeImage, Rect(cx, 0, cx, cy)); // ROI区域的右上
Mat q2(magnitudeImage, Rect(0, cy, cx, cy)); // ROI区域的左下
Mat q3(magnitudeImage, Rect(cx, cy, cx, cy)); // ROI区域的右下
//交换象限(左上与右下进行交换)
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
//交换象限(右上与左下进行交换)
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
//【8】归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
//此句代码的OpenCV3版为:
normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX);
//【9】显示效果图
imshow("频谱幅值", magnitudeImage);
waitKey();
return 0;
}
一. XML、YAML文件的打开
//第一种
FileStorage fs
fs.open("abs.xml",FileStorage::WRITE);
//第二种
FileStorage fs("abs.xml",FileStorage::WRITE);
//第一种
FileStorage fs
fs.open("abs.xml",FileStorage::READ);
//第二种
FileStorage fs("abs.xml",FileStorage::READ);
二. 进行文件读写操作
//写入文件
fs << "iterationNr" << 100;
//读取文件
int itNr;
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];
//数据结构的初始化
Mat R = Mat_<uchar>::eye(3,3),
Mat T = Mat_<double>::zeros(3,1);
//向 Mat中写入数据
fs << "R" << R;
fs << "T" << T;
//从 Mat中读取数据
fs ["R"] << R;
fs ["T"] >> T;
三. vector(arrays)和maps的输入和输出
对于vector结构输入和输出,要在第一个元素之前加上"[“,最后一个元素之前加上”]"。
fs << "strings" << "[";//开始读入string文本序列
fs << "imagel.jpg" << "Awesomeness" <<"baboon.jpg";
fs << "]";//关闭序列
对于map结构,替换成“{ }”
fs << "Mapping" ;//开始读入Mapping文本序列
fs << "{" << "One" << 1;
fs <<"Twp" << 2 << "}";//关闭序列
fs.release();
文件写入示例
#include "opencv2/opencv.hpp"
#include
using namespace cv;
int main()
{
//初始化
FileStorage fs("test.yaml", FileStorage::WRITE);
//开始文件写入
fs << "frameCount" << 5;
time_t rawtime; time(&rawtime);//获取time_t类型的当前时间
/*用localtime将time_t表示的时间转换为没有经过时区转换的UTC时间
然后再用asctime转换为我们常见的格式 Fri Jan 11 17:25:24 2008
*/
fs << "calibrationDate" << asctime(localtime(&rawtime));
Mat cameraMatrix = (Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
Mat distCoeffs = (Mat_<double>(5, 1) << 0.1, 0.01, -0.001, 0, 0);
fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
fs << "features" << "[";
for (int i = 0; i < 3; i++)
{
int x = rand() % 640;
//一般性:rand() % (b-a+1)+ a;就表示ab之间的一个随机整数。
int y = rand() % 480;
uchar lbp = rand() % 256;
fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
for (int j = 0; j < 8; j++)
fs << ((lbp >> j) & 1);
fs << "]" << "}";
}
fs << "]";
fs.release();
printf("\n文件读写完毕,请在工程目录下查看生成的文件~");
getchar();
return 0;
文件读取示例
#include "opencv2/opencv.hpp"
#include
using namespace cv;
using namespace std;
int main()
{
//改变console字体颜色
system("color 6F");
//初始化
FileStorage fs2("test.yaml", FileStorage::READ);
// 第一种方法,对FileNode操作
int frameCount = (int)fs2["frameCount"];
std::string date;
// 第二种方法,使用FileNode运算符> >
fs2["calibrationDate"] >> date;
Mat cameraMatrix2, distCoeffs2;
fs2["cameraMatrix"] >> cameraMatrix2;
fs2["distCoeffs"] >> distCoeffs2;
cout << "frameCount: " << frameCount << endl
<< "calibration date: " << date << endl
<< "camera matrix: " << cameraMatrix2 << endl
<< "distortion coeffs: " << distCoeffs2 << endl;
FileNode features = fs2["features"];
FileNodeIterator it = features.begin(), it_end = features.end();
int idx = 0;
std::vector<uchar> lbpval;
//使用FileNodeIterator遍历序列
for (; it != it_end; ++it, idx++)
{
cout << "feature #" << idx << ": ";
cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
// 我们也可以使用使用filenode > > std::vector操作符很容易的读数值阵列
(*it)["lbp"] >> lbpval;
for (int i = 0; i < (int)lbpval.size(); i++)
cout << " " << (int)lbpval[i];
cout << ")" << endl;
}
fs2.release();
//程序结束,输出一些帮助文字
printf("\n文件读取完毕,请输入任意键结束程序~");
getchar();
return 0;
}