1、图像显示
/**********************************************/
// Mat imread(const string& filename ,int flag=1);
// 第一个参数,const string&类型的filename,填我们需要载入的图片路径名。
// Windows位图 - *.bmp, *.dib
// *.jpeg, *.jpg, *.jpe *.jp2 *.png - *.pbm, *.pgm, *.ppm *.sr, *.ras *.tiff, *.tif
// 第二个参数,int类型的flags,为载入标识,它指定一个加载图像的颜色类型。
// 可以看到它自带缺省值1.所以有时候这个参数在调用时我们可以忽略,如果忽略表示三通道的彩色图像。
// enum
// {
// /* 8bit, color or not */
// CV_LOAD_IMAGE_UNCHANGED = -1,
// /* 8bit, gray */
// CV_LOAD_IMAGE_GRAYSCALE = 0,
// /* ?, color */
// CV_LOAD_IMAGE_COLOR = 1,
// /* any depth, ? */
// CV_LOAD_IMAGE_ANYDEPTH = 2,
// /* ?, any color */
// CV_LOAD_IMAGE_ANYCOLOR = 4
// };
//CV_LOAD_IMAGE_UNCHANGED,这个标识在新版本中被废置了,忽略。
//CV_LOAD_IMAGE_ANYDEPTH - 如果取这个标识的话,若载入的图像的深度为16位或者32位,就返回对应深度的图像,否则,就转换为8位图像再返回。
//CV_LOAD_IMAGE_COLOR - 如果取这个标识的话,总是转换图像到彩色一体
//CV_LOAD_IMAGE_GRAYSCALE - 如果取这个标识的话,始终将图像转换成灰度1
//如果输入有冲突的标志,将采用较小的数字值。比如CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYCOLOR 将载入3通道图。
//如果想要载入最真实的图像,选择CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR。
/**********************************************/
void main() //读图
{
// TODO: 在此添加控件通知处理程序代码
Mat myMat = imread("1.jpg");
Mat image0 = imread("1.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//载入最真实的图像
Mat image1 = imread("1.jpg", 0);//载入灰度图
Mat image2 = imread("1.jpg", 199);//载入3通道的彩色图像
Mat logo = imread("1.jpg");//载入3通道的彩色图像
imshow("原图1", myMat);
waitKey(0);
imshow("原图2", image0);
waitKey(0);
imshow("原图3", image1);
waitKey(0);
imshow("原图4", image2);
waitKey(0);
imshow("原图5", logo);
waitKey(0);
}
2、写图
// bool imwrite(const string& filename,InputArray img, const vector<int>& params=vector<int>() );
// 第一个参数,const string&类型的filename,填需要写入的文件名就行了,带上后缀,比如,“123.jpg”这样。
// 第二个参数,InputArray类型的img,一般填一个Mat类型的图像数据就行了。
// 第三个参数,const vector<int>&类型的params,表示为特定格式保存的参数编码,它有默认值vector<int>(),
// 所以一般情况下不需要填写。而如果要填写的话,有下面这些需要了解的地方:
// 对于JPEG格式的图片,这个参数表示从0到100的图片质量(CV_IMWRITE_JPEG_QUALITY),默认值是95.
// 对于PNG格式的图片,这个参数表示压缩级别(CV_IMWRITE_PNG_COMPRESSION)从0到9。
// 较高的值意味着更小的尺寸和更长的压缩时间,而默认值是3。
//
// void namedWindow(const string& winname,int flags=WINDOW_AUTOSIZE ); 顾名思义,namedWindow函数,用于创建一个窗口。
//第一个参数,const string&型的name,即填被用作窗口的标识符的窗口名称。
//第二个参数,int 类型的flags ,窗口的标识,可以填如下的值:
//WINDOW_NORMAL设置了这个值,用户便可以改变窗口的大小(没有限制)
//WINDOW_AUTOSIZE如果设置了这个值,窗口大小会自动调整以适应所显示的图像,并且不能手动改变窗口大小。
//WINDOW_OPENGL 如果设置了这个值的话,窗口创建的时候便会支持OpenGL。
void OnBnClickedimwrite()
{
// TODO: 在此添加控件通知处理程序代码
Mat mat(480, 640, CV_8UC4);
for (int i = 0; i < mat.rows; ++i)
{
for (int j = 0; j < mat.cols; ++j)
{
Vec4b&rgba = mat.at<Vec4b>(i, j);
rgba[0] = UCHAR_MAX;
rgba[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols) *UCHAR_MAX);
rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows) *UCHAR_MAX);
rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
}
}
vector<int>compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
try{
imwrite("透明Alpha值图.png", mat, compression_params);
}
catch (runtime_error& ex) {
fprintf(stderr, "图像转换成PNG格式发生错误:%s\n", ex.what());
}
}
3、图像腐蚀
void CTestCvDlg::OnBnClickedErode()
{
// TODO: 在此添加控件通知处理程序代码
//载入原图
Mat srcImage = imread("1.jpg");
//显示原图
imshow("【原图】腐蚀操作", srcImage);
//进行腐蚀操作
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dstImage;
erode(srcImage, dstImage, element);
//显示效果图
imshow("【效果图】腐蚀操作", dstImage);
waitKey(0);
}
4、显示视频
int main()
{
VideoCapture capture(0);//opencv调用摄像头读取视频
//【2】循环显示每一帧
while (1)
{
Mat frame;//定义一个Mat变量,用于存储每一帧的图像
capture >> frame; //读取当前帧
imshow("读取视频", frame);
if (waitKey(30) == 27)//按下Esc键退出读取视频操作
break;
}
return 0;
}
5、Canny边缘检测
void CTestCvDlg::OnBnClickedCanny()
{
// TODO: 在此添加控件通知处理程序代码
//【0】载入原始图
Mat srcImage = imread("1.jpg"); //工程目录下应该有一张名为1.jpg的素材图
imshow("【原始图】Canny边缘检测", srcImage); //显示原始图
Mat dstImage, edge, grayImage; //参数定义
//【1】创建与src同类型和大小的矩阵(dst)
dstImage.create(srcImage.size(), srcImage.type());
//【2】将原图像转换为灰度图像
//此句代码的OpenCV2版为:
//cvtColor( srcImage, grayImage, CV_BGR2GRAY );
//此句代码的OpenCV3版为:
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
//【3】先用使用 3x3内核来降噪
blur(grayImage, edge, Size(3, 3));
//【4】运行Canny算子
Canny(edge, edge, 3, 9, 3);
//【5】将g_dstImage内的所有元素设置为0
dstImage = Scalar::all(0);
//【6】使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
srcImage.copyTo(dstImage, edge);
//【7】显示效果图
imshow("【效果图】Canny边缘检测", edge);
waitKey(0);
}
6、鼠标操作
/****************************************/
//void::SetMouseCallback为鼠标回调函数
//void setMouseCallback(conststring& winname, MouseCallback onMouse, void* userdata= 0)
//第一个参数 const string& 类型的winname,窗口的名字
//第二个参数 MouseCallback 类型的onMouse, 指定的窗口里每次鼠标事件发生的时候,被调用的函数指针
//第三个参数 void* 类型的userdata,用户定义的传递到回调函数的参数,有默认值0.
/****************************************/
void FunctionAnalysis::OnBnClickedMouse() //鼠标操作
{
// TODO: 在此添加控件通知处理程序代码
//【1】参数准备
g_rectangle = Rect(-1, -1, 0, 0);
Mat srcImage(600, 800, CV_8UC3), tempImage;
srcImage.copyTo(tempImage);
g_rectangle = Rect(-1, -1, 0, 0);
srcImage = Scalar::all(0);
//【2】设置鼠标操作回调函数
namedWindow(WINIDOW_NAME1);
setMouseCallback(WINIDOW_NAME1, on_MouseHandle, (void*)&srcImage);
//【3】程序主循环,当进行绘制的标示符为真时,进行绘制
while (1)
{
srcImage.copyTo(tempImage);//拷贝源图到临时变量
if (g_bDrawingBox)
{
DrawRectangle(tempImage, g_rectangle);////当进行绘制的标识符为真,则进行绘制
}
imshow(WINIDOW_NAME1, tempImage);
if (waitKey(10) == 27)
{
break; //按下ESC键,程序退出
}
}
}
7、滑动条
//Mat img;
//int threshval = 160; //轨迹条滑块对应的值,给初值160
//-----------------------------【on_trackbar( )函数】------------------------------------
// 描述:轨迹条的回调函数
//-----------------------------------------------------------------------------------------------
static void on_Trackbar(int, void*)
{
//求出当前alpha值相对于最大值的比例
g_dAlphaValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
//则beta值为1减去alpha值
g_dBetaValue = (1.0 - g_dAlphaValue);
//根据alpha和beta值进行线性混合
addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
//显示效果图
imshow(WINDOW_NAME, g_dstImage);
}
/***********************************************/
//创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上.
//0、int createTrackbar(conststring& trackbarname, conststring& winname, int* value, int count, TrackbarCallback onChange = 0, void* userdata = 0);
//1、const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
//2、const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
//3、int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
//4、int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
//5、TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。
//6、void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。
/***********************************************/
void OnBnClickedcreatetrackbar()
{
// TODO: 在此添加控件通知处理程序代码
//加载图像 (两图像的尺寸需相同)
g_srcImage1 = imread("1.jpg");
if (!g_srcImage1.data)
{
printf("读取第一幅图片错误,请确定目录下是否有imread函数指定图片存在~! \n");
}
g_srcImage2 = imread("1.jpg");
if (!g_srcImage2.data)
{
printf("读取第一幅图片错误,请确定目录下是否有imread函数指定图片存在~! \n");
}
//设置滑动条初值为70
g_nAlphaValueSlider = 70;
//创建窗体
namedWindow(WINDOW_NAME, 1);
//在创建的窗体中创建一个滑动条控件
char TrackbarName[50];
sprintf_s(TrackbarName, "透明值 %d", g_nMaxAlphaValue);
createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);
//结果在回调函数中显示
on_Trackbar(g_nAlphaValueSlider, 0);
//按任意键退出
waitKey(0);
}
8、图像的载入、显示和输出到文件
void CTestCvDlg::OnBnClickedimreadwrite()
{
// TODO: 在此添加控件通知处理程序代码
//------【一、图像的载入和显示】--------------
Mat girl = imread("girl.png"); //载入图像到Mat
namedWindow("1动漫图"); //创建一个名为“1动漫图”的窗口
imshow("1动漫图",girl); //显示名为“1动漫图”的窗口
waitKey();
//------【二、初级图像混合】------------------
//载入图片
Mat image = imread("dota.png",199);
Mat logo = imread("logo.png");
//载入先后显示
namedWindow("2原图");
imshow("2原图",image);
namedWindow("3原图");
imshow("3原图",logo);
//定义一个Mat类型,用于存放,图像的ROI
Mat imageROI;
//方法一
//imageROI = image(Rect(800, 350, logo.cols, logo.rows));
//方法二
imageROI=image(Range(350,350+logo.rows),Range(800,800+logo.cols));//有bug
//将logo加到原图上
addWeighted(imageROI, 0.5, logo, 0.3, 0., imageROI);
//显示结果
namedWindow("3原图+logo图");
imshow("3原图+logo图", image);
//--------------【三、图像的输出】---------------------
//输出一张jpg图片到工程目录下
imwrite("dota.jpg", image);
waitKey(0);
}