Ctrl+K Ctrl+C 批量添加代码注释

Ctrl+K Ctrl+U 批量删除代码注释

#include <opencv2/opencv.hpp>
#include<vector>
#include<time.h>//XML和YAML文件的写入
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include "opencv2/core/core.hpp"
//#pragma warning(disable : 4996);
using namespace std;
using namespace cv;
#define WINDOW_NAME "【程序窗口】"//为窗口标题定义的宏

/*-----------------边缘检测--begin------------------------*/

原图,原图的灰度版,目标图
//Mat g_srcImage, g_srcGrayImage, g_dstImage;
//
Canny边缘检测相关变量
//Mat g_cannyDetectedEdges;
//int g_cannyLowThreshold = 1;//TrackBar位置参数
//
Sobel边缘检测相关变量
//Mat g_sobelGradient_X, g_sobelGradient_Y;
//Mat g_sobelAbsGradient_X, g_sobelAbsGradient_Y;
//int g_sobelKernelSize = 1;
//
Scharr滤波器相关变量
//Mat g_scharrGradient_X, g_scharrGradient_Y;
//Mat g_scharrAbsGradient_X, g_scharrAbsGradient_Y;
//
//static void on_Canny(int, void*);//Canny边缘检测窗口滚动条的回调函数
//static void on_Sobel(int, void*);//Sobel边缘检测窗口滚动条的回调函数
//void Scharr();//封装了Scharr边缘检测相关代码的函数
//
//int main(int argc,char** argv)
//{
//    system("color 2F");
//
//    g_srcImage = imread("2.jpg");
//    if (!g_srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//
//    namedWindow("【原始图】");
//    imshow("【原始图", g_srcImage);
//
//    //创建与src同类型和大小的矩阵(dst)
//    g_dstImage.create(g_srcImage.size(), g_srcImage.type());
//
//    //将原图像转换为灰度图像
//    cvtColor(g_srcImage, g_srcGrayImage, COLOR_BGR2GRAY);
//
//    //创建显示窗口
//    namedWindow("【效果图】Canny边缘检测", WINDOW_AUTOSIZE);
//    namedWindow("【效果图】Sobel边缘检测", WINDOW_AUTOSIZE);
//
//    //创建trackbar
//    createTrackbar("参数值:", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny);
//    createTrackbar("参数值:", "【效果图】Sobel边缘检测", &g_sobelKernelSize, 3, on_Sobel);
//
//    //调用回调函数
//    on_Canny(0, 0);
//    on_Sobel(0, 0);
//
//    //调用封装了Scharr边缘检测代码的函数
//    Scharr();
//
//    //轮询获取按键信息,若按下Q,程序退出
//    while((char(waitKey(1))!='q')){ }
//    return 0;

//}
//描述:Canny边缘检测窗口滚动条的回调函数

//void on_Canny(int, void*)
//{
//    //先使用3*3内核来降噪
//    blur(g_srcGrayImage, g_cannyDetectedEdges, Size(3, 3));
//
//    //运行我们的Canny算子
//    Canny(g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold * 3, 3);
//
//    //先将g_dstImage内所有的元素设置为0
//    g_dstImage = Scalar::all(0);
//
//    //使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
//    g_srcImage.copyTo(g_dstImage, g_cannyDetectedEdges);
//
//    //显示效果图
//    imshow("【效果图】Canny边缘检测", g_dstImage);
//}
//
描述:Sobel边缘检测窗口滚动条的回调函数
//void on_Sobel(int, void*)
//{
//    //求X方向梯度
//    Sobel(g_srcImage, g_sobelGradient_X, CV_16S, 1, 0, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);
//    convertScaleAbs(g_sobelGradient_X, g_sobelAbsGradient_X);//计算绝对值,并将结果转换成8位
//
//    //求Y方向梯度
//    Sobel(g_srcImage, g_sobelGradient_Y, CV_16S, 0, 1, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);
//    convertScaleAbs(g_sobelGradient_Y, g_sobelAbsGradient_Y);//计算绝对值,并将结果转换成8位
//
//    //合并梯度
//    addWeighted(g_sobelAbsGradient_X, 0.5, g_sobelAbsGradient_Y, 0.5, 0, g_dstImage);
//}
//
描述:封装了Scharr边缘检测相关代码的函数
//void Scharr()
//{
//    //求X方向梯度
//    Scharr(g_srcImage, g_scharrGradient_X, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
//    convertScaleAbs(g_scharrGradient_X, g_scharrAbsGradient_X);//计算绝对值,并将结果转换成8位
//    //求Y方向梯度
//    Scharr(g_srcImage, g_scharrGradient_Y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT);
//    convertScaleAbs(g_scharrGradient_Y, g_scharrAbsGradient_Y);//计算绝对值,并将结果转换成8位
//
//    //合并梯度
//    addWeighted(g_scharrAbsGradient_X, 0.5, g_scharrAbsGradient_Y, 0.5, 0, g_dstImage);
//
//    //显示效果图
//    imshow("【效果图】Scharr滤波器", g_dstImage);
//}
/*-----------------边缘检测--end------------------------*/

/*-----------------Scharr滤波器--begin-------------------*/

//int main()
//{
//    Mat grad_x, grad_y;
//    Mat abs_grad_x, abs_grad_y, dst;
//
//    Mat src = imread("2.jpg");
//    imshow("【原始图】Scharr滤波器", src);
//
//    //求X方向梯度
//    Scharr(src, grad_x, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
//    convertScaleAbs(grad_x, abs_grad_x);
//    imshow("【效果图】X方向Scharr", abs_grad_x);
//
//    //求Y方向梯度
//    Scharr(src, grad_y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT);
//    convertScaleAbs(grad_y, abs_grad_y);
//    imshow("【效果图】Y方向Scharr", abs_grad_y);
//
//    //合并梯度
//    addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
//
//    //显示效果图
//    imshow("【效果图】合并梯度后Scharr", dst);
//
//    waitKey(0);
//    return 0;
//}

/*-----------------Scharr滤波器--end-------------------*/

/*------------------Laplacian算子的使用--begin------------*/

//int main()
//{
//    //变量的定义
//    Mat src, src_gray, dst, abs_dst;
//
//    //载入原始图
//    src = imread("2.jpg");
//
//    //显示原始图
//    imshow("【原始图】图像Laplace变换", src);
//
//    //使用高斯滤波消除噪声
//    GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
//
//    //转换为灰度图
//    cvtColor(src, src_gray, COLOR_RGB2GRAY);
//
//    //使用Laplace函数
//    Laplacian(src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);
//
//    //计算绝对值,并将结果转换成8位
//    convertScaleAbs(dst, abs_dst);
//
//    //显示效果图
//    imshow("【效果图】图像Laplace变换", abs_dst);
//    waitKey(0);
//    return 0;
//}

/*------------------Laplacian算子的使用--end------------*/
/*------------------Sobel算子的使用--begin-------------------*/

//int main()
//{
//    //创建grad_x和grad_y矩阵
//    Mat grad_x, grad_y;
//    Mat abs_grad_x, abs_grad_y, dst;
//
//    //载入原始图
//    Mat src = imread("2.jpg");
//
//    //显示原始图abs_grad
//    imshow("【原始图】sobel边缘检测", src);
//
//    //求X方向梯度
//    Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
//    convertScaleAbs(grad_x, abs_grad_x);
//    imshow("【效果图】X方向Sobel", abs_grad_x);
//
//    //求Y方向梯度
//    Sobel(src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
//    convertScaleAbs(grad_y, abs_grad_y);
//    imshow("【效果图】Y方向Sobel", abs_grad_y);
//
//    //合并梯度(近似)
//    addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
//    imshow("【效果图】整体方向Sobel", dst);
//
//    waitKey(0);
//    return 0;
//}

/*------------------Sobel算子的使用--end-------------------*/

/*------------------Canny边缘检测--begin---------------------*/

//int main()
//{
//    Mat src = imread("2.jpg");
//    Mat src1 = src.clone();
//
//    imshow("【原始图】Canny边缘检测", src);
//
//    Mat dst, edge, gray;
//    //创建与src同类型核大小的矩阵(dst)
//    dst.create(src1.size(), src1.type());
//
//    //将原图像转换为灰度图像
//    cvtColor(src1, gray, COLOR_BGR2GRAY);
//
//    //先用使用3*3内核来降噪
//    blur(gray, edge, Size(3,3));
//
//    //运行Canny算子
//    Canny(edge, edge,  3, 9, 3);
//
//    //将g_dstImage内的所有元素设置为0
//    dst = Scalar::all(0);
//
//    //使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
//    src1.copyTo(dst, edge);
//
//    //显示效果图
//    imshow("【效果图】Canny边缘检测2", dst);
//    waitKey(0);
//    return 0;
//}

/*------------------Canny边缘检测--end---------------------*/

/*-----------------基本阈值操作---begin-----------------------*/

//int g_nThresholdValue = 100;
//int g_nThresholdType = 3;
//Mat g_srcImage, g_grayImage, g_dstImage;
//
//static void ShowHelpText();//输出帮助文字
//void on_Threshold(int, void*);//回调函数
//
//int main()
//{
//    //读入源图片
//    g_srcImage = imread("2.jpg");
//    if (!g_srcImage.data)
//    {
//        printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
//        return false;
//    }
//
//    //存留一份原图的灰度值
//    cvtColor(g_srcImage, g_grayImage, COLOR_RGB2GRAY);
//
//    //创建窗口并显示原始图
//    namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
//
//    //创建滑动条来控制阈值
//    createTrackbar("模式", WINDOW_NAME, &g_nThresholdType, 4, on_Threshold);
//    createTrackbar("参数值", WINDOW_NAME, &g_nThresholdValue, 255, on_Threshold);
//
//    //初始化自定义的阈值回调函数
//    on_Threshold(0, 0);
//
//    //轮询等待用户按键,如果ESC键按下则退出程序
//    while (1)
//    {
//        int key;
//        key = waitKey(20);
//        if ((char)key == 27)
//        {
//            break;
//        }
//    }
//}
//    void on_Threshold(int, void * )
//    {
//        //调用阈值函数
//        threshold(g_grayImage, g_dstImage, g_nThresholdValue, 255, g_nThresholdType);
//        //更新效果图
//        imshow(WINDOW_NAME, g_dstImage);
//    }

/*-----------------基本阈值操作---end-----------------------*/

/*-----------------图像金字塔与图片尺寸缩放---begin-------------*/

//Mat g_srcImage, g_dstImage, g_tmpImage;
//int main()
//{
//    //载入原图
//    g_srcImage = imread("2.jpg");//工程目录下需要有一张名为2.jpg的测试图像,且其尺寸需被2的N次方整除,N为可以缩放的次数
//    if (!g_srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//    //创建显示窗口
//    namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
//    imshow(WINDOW_NAME, g_srcImage);
//
//    //参数赋值
//    g_tmpImage = g_srcImage;
//    g_dstImage = g_tmpImage;
//
//    int key = 0;
//
//    //轮询获取按键信息
//    while (1)
//    {
//        key = waitKey(9);//读取键值到key变量中
//        //根据key变量的值,进行不同的操作
//        switch (key)
//        {
//        case 27://按键ESC
//            return 0;
//            break;
//
//        case 'q':
//            return 0;
//            break;
//
//        case 'a':
//            pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
//            printf(">检测到按键【A】被按下,开始进行基于【pyrUp】函数的图片放大:图片尺寸*2\n");
//            break;
//        case 'w':
//            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
//            printf(">检测到按键【W】被按下,开始进行基于【resize】函数的图片放大:图片尺寸*2\n");
//            break;
//        case '1':
//            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
//            printf(">检测到按键【1】被按下,开始进行基于【resize】函数的图片放大:图片尺寸*2\n");
//            break;
//        case '3':
//            pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
//            printf(">检测到按键【3】被按下,开始进行基于【pyrUp】函数的图片放大:图片尺寸*2\n");
//            break;
//        case 'd':
//            pyrDown(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
//            printf(">检测到按键【D】被按下,开始进行基于【pyrDown】函数的图片缩小:图片尺寸/2\n");
//            break;
//        case 's':
//            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
//            printf(">检测到按键【S】被按下,开始进行基于【resize】函数的图片缩小:图片尺寸/2\n");
//            break;
//        case '2':
//            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2),(0,0),(0,0),2);
//            printf(">检测到按键【2】被按下,开始进行基于【resize】函数的图片缩小:图片尺寸/2\n");
//            break;
//        case '4':
//            pyrDown(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
//            printf(">检测到按键【4】被按下,开始进行基于【pyrDown】函数的图片缩小:图片尺寸/2\n");
//            break;
//        }
//        imshow(WINDOW_NAME, g_dstImage);
//        //将g_dstImage赋给g_tmpImage,方便下一次循环
//        g_tmpImage=g_dstImage;
//
//    }
//    return 0;
//}

/*-----------------图像金字塔与图片尺寸缩放---end-------------*/

/*--------------------漫水填充-----begin-----------------------*/

//Mat g_srcImage, g_dstImage, g_grayImage, g_maskImage;//定义原始图、目标图、灰度图、掩模图
//int g_nFillMode = 1;//漫水填充的模式
//int g_nLowDifference = 20, g_nUpDifference = 20;//负差最大值、正差最大值
//int g_nConnectivity = 4;//表示floodFill函数标识低八位的连通值
//int g_bIsColor = true;//是否为彩色图的标识符布尔值
//int g_bUseMask = false;//是否显示掩膜窗口的布尔值
//int g_nNewMaskVal = 255;//新的重新绘制的像素值
//
鼠标消息onMouse回调函数
//static void onMouse(int event, int x, int y, int, void*)
//{
//    //若鼠标左键没有按下,便返回
//    if (event != CV_EVENT_LBUTTONDOWN)
//    {
//        return;
//    }
//    //调用floodFill函数之前的参数准备部分
//    Point seed = Point(x, y);
//    int LowDifference = g_nFillMode == 0 ? 0 : g_nLowDifference;//空范围的漫水填充,此值设为0,否则设为全局的n_nLowDifference
//    int UpDifference = g_nFillMode == 0 ? 0 : g_nUpDifference;//空范围的漫水填充,此值设为0,否则设为全局的g_nUpDifference
//
//    //标识符的0~7位为g_nConnectivity,8~15位为g_nNewMaskVal左移8位的值,16~23位为CV_FLOODFILL_FIXED_RANGE或者0。
//    int flags = g_nConnectivity + (g_nNewMaskVal << 8) + (g_nFillMode == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);
//
//    //随机生成bgr值
//    int b = (unsigned)theRNG() & 255;//随机返回一个0~255之间的值
//    int g = (unsigned)theRNG() & 255;//随机返回一个0~255之间的值
//    int r = (unsigned)theRNG() & 255;//随机返回一个0~255之间的值
//    Rect ccomp;//定义重绘区域的最小边界矩形区域
//
//    Scalar newVal = g_bIsColor ? Scalar(b, g, r) : Scalar(r * 0.299 + g * 0.587 + b * 0.114);//在重绘区域像素的新值,若是彩色图模式,取Scalar(b,g,r);若是灰度图模式,取Scalar(r*0.299+g*0.587+b*0.114)
//    Mat dst = g_bIsColor ? g_dstImage : g_grayImage;//目标图的赋值
//    int area;
//
//    //正式调用floodFill函数
//    if (g_bUseMask)
//    {
//        threshold(g_maskImage, g_maskImage, 1, 128, CV_THRESH_BINARY);
//        area = floodFill(dst, g_maskImage, seed, newVal, &ccomp, Scalar(LowDifference, LowDifference, LowDifference), Scalar(UpDifference, UpDifference, UpDifference), flags);
//        imshow("mask", g_maskImage);
//    }
//    else
//    {
//        area = floodFill(dst, seed, newVal, &ccomp, Scalar(LowDifference, LowDifference, LowDifference), Scalar(UpDifference, UpDifference, UpDifference), flags);
//    }
//    imshow("效果图", dst);
//    cout << area << "个像素被重绘\n";
//}
//
//int main()
//{
//    //载入原图
//    g_srcImage = imread("2.jpg", 1);
//    if (!g_srcImage.data)
//    {
//        printf("读取图片image0错误~!\n");
//        return false;
//    }
//    g_srcImage.copyTo(g_dstImage);//复制源图到目标图
//    cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);//转换三通道的image0到灰度图
//    g_maskImage.create(g_srcImage.rows + 2, g_srcImage.cols + 2, CV_8UC1);//利用image0的尺寸来初始化掩膜mask
//    namedWindow("效果图", CV_WINDOW_AUTOSIZE);
//
//    //创建Trackbar
//    createTrackbar("负差最大值", "效果图", &g_nLowDifference, 255, 0);
//    createTrackbar("正差最大值", "效果图", &g_nUpDifference, 255, 0);
//    //鼠标回调函数
//    setMouseCallback("效果图", onMouse, 0);
//    //循环轮询按键
//    while (1)
//    {
//        //先显示效果图
//        imshow("效果图", g_bIsColor ? g_dstImage : g_grayImage);
//        //获取键盘按键
//        int c = waitKey(0);
//        //判断ESC是否按下,若按下便退出
//        if ((c & 255) == 27)
//        {
//            cout << "程序退出........\n";
//            break;
//        }
//        //根据按键的不同,进行各种操作
//        switch ((char)c)
//        {
//            //如果键盘"1"被按下,效果图在在灰度图,彩色图之间互换
//            case'1':
//                if (g_bIsColor)//若原来为彩色,转为灰度图,并且将掩膜mask所有元素设置为0
//                {
//                    cout << "键盘'1'被按下,切换彩色/灰度模式,当前操作为将【彩色模式】转换为【灰度模式】\n";
//                    cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
//                    g_maskImage = Scalar::all(0);//将mask所有元素设置为0
//                    g_bIsColor = false;//将标识符置为false,表示当前图像不为彩色,而是灰度
//                }
//                else//若原来为灰度图,便将原来的彩图image0再次复制给image,并将掩膜mask所有元素设置为0
//                {
//                    cout << "键盘'1'被按下,切换彩色/灰度模式,当前操作为将【彩色模式】切换为【灰度模式】\n";
//                    g_srcImage.copyTo(g_dstImage);
//                    g_maskImage = Scalar::all(0);
//                    g_bIsColor = true;//将标识符置为true,表示当前图像模式为彩色
//                }
//                break;
//            //如果键盘按键"2"被按下,显示/隐藏掩膜窗口
//            case'2':
//                if (g_bUseMask)
//                {
//                    destroyWindow("mask");
//                    g_bUseMask = false;
//                }
//                else
//                {
//                    namedWindow("mask", 0);
//                    g_maskImage = Scalar::all(0);
//                    imshow("mask", g_maskImage);
//                    g_bUseMask = true;
//                }
//                break;
//            //如果键盘"3"被按下,恢复原始图像
//            case'3':
//                cout << "按键'3'被按下,恢复原始图像\n";
//                g_srcImage.copyTo(g_dstImage);
//                cvtColor(g_dstImage, g_grayImage, COLOR_BGR2GRAY);
//                g_maskImage = Scalar::all(0);
//                break;
//            //如果键盘"4"被按下,使用空范围的漫水填充
//            case'4':
//                cout << "按键'5'被按下,使用空范围的漫水填充\n";
//                g_nFillMode = 0;
//                break;
//            //如果键盘"5"被按下,使用渐变、固定范围的漫水填充
//            case'5':
//                cout << "按键'5'被按下,使用渐变、固定范围的漫水填充\n";
//                g_nFillMode = 1;
//                break;
//            //如果键盘"6"被按下,使用渐变、浮动范围的漫水填充
//            case'6':
//                cout << "按键'6'被按下,使用渐变、浮动范围的漫水填充\n";
//                g_nFillMode = 2;
//                break;
//            //如果键盘"7"被按下,操作标识符的低八位使用4位的连接模式
//            case'7':
//                cout << "按键'7'被按下,操作标识符的低八位使用4位的连接模式\n";
//                g_nConnectivity=4;
//                break;
//            //如果键盘"8"被按下,操作标识符的低八位使用4位的连接模式
//            case'8':
//                cout << "按键'8'被按下,操作标识符的低八位使用8位的连接模式\n";
//                g_nConnectivity = 8;
//                break;
//        }
//    }
//    return 0;
//}

/*--------------------漫水填充-----end-----------------------*/

/*---------------------形态学滤波:开运算、闭运算、形态学梯度、顶帽、黑帽-----------begin---------*/

//Mat g_srcImage, g_dstImage;
//int g_nElementShape = MORPH_RECT;//元素结构的形状
//
变量接受的TrackBar位置参数
//int g_nMaxIterationNum = 10;
//int g_nOpenCloseNum = 0;
//int g_nErodeDilateNum = 0;
//int g_nTopBlackHatNum = 0;
//
//static void on_OpenClose(int, void*);//回调函数
//static void on_ErodeDilate(int, void*);//回调函数
//static void on_TopBlackHat(int, void*);//回调函数
//static void ShowHelpText();//帮助文字显示
//
//int main()
//{
//    //载入原图
//    g_srcImage = imread("2.jpg");
//    if (!g_srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//
//    //显示原始图
//    namedWindow("【原始图】");
//    imshow("【原始图】", g_srcImage);
//
//    //创建三个窗口
//    namedWindow("【开运算/闭运算】", 1);
//    namedWindow("【腐蚀/膨胀】", 1);
//    namedWindow("【顶帽/黑帽】", 1);
//
//    //参数赋值
//    g_nOpenCloseNum = 9;
//    g_nErodeDilateNum = 9;
//    g_nTopBlackHatNum = 2;
//
//    //分别为三个窗口创建滚动条
//    createTrackbar("迭代值", "【开运算/闭运算】", &g_nOpenCloseNum, g_nMaxIterationNum * 2 + 1, on_OpenClose);
//    createTrackbar("迭代值", "【腐蚀/膨胀】", &g_nErodeDilateNum, g_nMaxIterationNum * 2 + 1, on_ErodeDilate);
//    createTrackbar("迭代值", "【顶帽/黑帽】", &g_nTopBlackHatNum, g_nMaxIterationNum * 2 + 1, on_TopBlackHat);
//
//    //轮询获取按键信息
//    while (1)
//    {
//        int c;
//        //执行回调函数
//        on_OpenClose(g_nOpenCloseNum, 0);
//        on_ErodeDilate(g_nErodeDilateNum, 0);
//        on_TopBlackHat(g_nTopBlackHatNum, 0);
//
//        //获取按键
//        c = waitKey(0);
//
//        //按下键盘按键Q或者ESC,程序退出
//        if ((char)c == 'q' || (char)c == 27)
//            break;
//        //按下键盘按键1,使用椭圆(Elliptic)结构元素结构元素MORPH_ELLIPSE
//        if ((char)c == 49)//键盘按键1的ASII码为49
//            g_nElementShape = MORPH_ELLIPSE;
//        //按下键盘按键2,使用矩形(Rectangle)结构元素MORPH_RECT
//        else if ((char)c == 50)//键盘按键2的ASII码为50
//            g_nElementShape = MORPH_RECT;
//        //按下键盘按键3,使用十字形(Cross-shaped)结构元素MORPH_CROSS
//        else if ((char)c == 51)//键盘按键3的ASII码为51
//            g_nElementShape = MORPH_CROSS;
//        //按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
//        else if ((char)c == ' ')
//            g_nElementShape = (g_nElementShape + 1) % 3;
//    }
//    return 0;
//}
//
开运算/闭运算窗口回调函数
//static void on_OpenClose(int, void*)
//{
//    //偏移量的定义
//    int offset = g_nOpenCloseNum - g_nMaxIterationNum;//偏移量
//    int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
//    //自定义核
//    Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
//    //进行操作
//    if (offset < 0)
//    {
//        morphologyEx(g_srcImage, g_dstImage, CV_MOP_OPEN, element);
//    }
//    else
//    {
//        morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
//    }
//    //显示图像
//    imshow("【开运算/闭运算】", g_dstImage);
//}
//
腐蚀/膨胀窗口的回调函数
//static void on_ErodeDilate(int, void*)
//{
//    //偏移量的定义
//    int offset = g_nErodeDilateNum - g_nMaxIterationNum;//偏移量
//    int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
//    //自定义核
//    Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1,Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset));
//    //进行操作
//    if (offset < 0)
//        erode(g_srcImage, g_dstImage, element);
//    else
//        dilate(g_srcImage, g_dstImage, element);
//    //显示图像
//    imshow("【腐蚀/膨胀】", g_dstImage);
//}
//
顶帽运算/黑帽运算窗口回调函数
//static void on_TopBlackHat(int, void*)
//{
//    //偏移量的定义
//    int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量
//    int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
//    //自定义核
//    Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
//    //进行操作
//    if (offset < 0)
//        morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
//    else
//        morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
//    //显示图像
//    imshow("【顶帽/黑帽】", g_dstImage);
//
//}

/*---------------------形态学滤波:开运算、闭运算、形态学梯度、顶帽、黑帽-----------end---------*/

/*---------------------腐蚀与膨胀Begin-------------------*/

//Mat g_srcImage, g_dstImage;
//int g_nTrackbarNumber = 0;//0表示腐蚀erode,1表示膨胀dilate
//int g_nStructElementSize = 3;//结构元素(内核矩阵)的尺寸
//
//void Process();//膨胀与腐蚀的处理函数
//void on_TrackbarNumChange(int, void*);
//void on_ElementSizeChange(int, void*);
//
//int main()
//{
//    system("color5E");
//
//    g_srcImage = imread("2.jpg");
//    if (!g_srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//
//    namedWindow("【原始图】");
//    imshow("【原始图】", g_srcImage);
//
//    //进行初次腐蚀操作并显示效果图
//    namedWindow("【效果图】");
//    //获取自定义核
//    Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
//    erode(g_srcImage, g_dstImage, element);
//    imshow("【效果图】", g_dstImage);
//
//    //创建轨迹条
//    createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumber, 1, on_TrackbarNumChange);
//    createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange);
//
//    //轮询获取按键信息,按下q键,程序退出
//    while (char(waitKey(1)) != 'q') {}
//    return 0;
//}
//
//void Process()
//{
//    //获取自定义核
//    Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
//    //进行腐蚀或膨胀操作
//    if (g_nTrackbarNumber == 0)
//    {
//        erode(g_srcImage, g_dstImage, element);
//    }
//    else
//    {
//        dilate(g_srcImage, g_dstImage, element);
//    }
//    //显示效果图
//    imshow("【效果图】", g_dstImage);
//}
//
腐蚀和膨胀之间切换开关的回调函数
//void on_TrackbarNumChange(int, void*)
//{
//    //腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
//    Process();
//}
//
腐蚀和膨胀操作内核改变时的回调函数
//void on_ElementSizeChange(int, void*)
//{
//    //内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
//    Process();
//}

/*---------------------腐蚀与膨胀End-------------------*/

/*-----------------------图像非线性滤波综合示例 Begin---------------------*/

//Mat g_srcImage, g_dstImage1, g_dstImage2;
//int g_nMedianBlurValue = 10;//中值滤波参数值
//int g_nBilateralFilterValue = 10;//双边滤波参数值
//
轨迹条回调函数
//static void on_MedianBlur(int, void*);//中值滤波器
//static void on_BilateralFilter(int, void*);//双边滤波器
//
//int main()
//{
//    system("color 5E");
//
//    //载入原图
//    g_srcImage = imread("2.jpg", 1);
//    if (!g_srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//
//    //复制原图到Mat类型中
//    g_dstImage1 = g_srcImage.clone();
//    g_dstImage2 = g_srcImage.clone();
//
//    //显示原图
//    namedWindow("【<0>原图窗口】", 1);
//    imshow("【<0>原图窗口】", g_srcImage);
//
//    //创建窗口
//    namedWindow("【<1>中值滤波】", 1);
//    //创建轨迹条
//    createTrackbar("参数值:", "【<1>中值滤波】", &g_nMedianBlurValue, 50, on_MedianBlur);
//    on_MedianBlur(g_nMedianBlurValue, 0);
//
//    //创建窗口
//    namedWindow("【<2>双边滤波】", 1);
//    //创建轨迹条
//    createTrackbar("参数值:", "【<2>双边滤波】", &g_nBilateralFilterValue, 50, on_BilateralFilter);
//    on_BilateralFilter(g_nBilateralFilterValue, 0);
//    while(char(waitKey(1))!='q'){}
//    return 0;
//}
//
中值滤波操作的回调函数
//static void on_MedianBlur(int, void*)
//{
//    medianBlur(g_srcImage, g_dstImage1, g_nMedianBlurValue * 2 + 1);
//    imshow("【<1>中值滤波】", g_dstImage1);
//}
//
双边滤波的回调函数
//static void on_BilateralFilter(int, void*)
//{
//    bilateralFilter(g_srcImage, g_dstImage2, g_nBilateralFilterValue, g_nBilateralFilterValue * 2, g_nBilateralFilterValue / 2);
//    imshow("【<2>双边滤波】", g_dstImage2);
//}

/*-----------------------图像非线性滤波综合示例 End----------------------*/

/*-----------------------图像线性滤波综合示例 Begin---------------------------------*/

//Mat g_srcImage, g_dstImage1, g_dstImage2, g_dstImage3;//存储图片的Mat类型
//int g_nBoxFilterValue = 3;//方框滤波参数值
//int g_nMeanBlurValue = 3;//均值滤波参数值
//int g_nGaussianBlurValue = 3;//高斯滤波参数值
//
轨迹条的回调函数
//static void on_BoxFilter(int, void*);
//static void on_MeanBlur(int, void*);
//static void on_GaussianBlur(int, void*);
//
//int main()
//{
//    system("color5E");
//    g_srcImage = imread("1.jpg", 1);
//    if (!g_srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//
//    //复制原图到三个Mat类型中
//    g_dstImage1 = g_srcImage.clone();
//    g_dstImage2 = g_srcImage.clone();
//    g_dstImage3 = g_srcImage.clone();
//    //显示原图
//    namedWindow("【<0>原图窗口】", 1);
//    imshow("【<0>原图窗口】", g_srcImage);
//
//    //=========================【<1>方框滤波】=============
//    //创建窗口
//    namedWindow("【<1>方框滤波】", 1);
//    //创建轨迹条
//    createTrackbar("内核值:", "【<1>方框滤波】", &g_nBoxFilterValue, 40, on_BoxFilter);
//    on_BoxFilter(g_nBoxFilterValue, 0);
//    //=====================================================
//
//    //=========================【<2>均值滤波】=============
//    //创建窗口
//    namedWindow("【<2>均值滤波】", 1);
//    //创建轨迹条
//    createTrackbar("内核值:", "【<2>均值滤波】", &g_nMeanBlurValue, 40, on_MeanBlur);
//    on_MeanBlur(g_nMeanBlurValue, 0);
//    //=====================================================
//
//    //=========================【<3>高斯滤波】=============
//    //创建窗口
//    namedWindow("【<3>高斯滤波】", 1);
//    //创建轨迹条
//    createTrackbar("内核值:", "【<3>高斯滤波】", &g_nGaussianBlurValue, 40, on_GaussianBlur);
//    on_GaussianBlur(g_nGaussianBlurValue, 0);
//    //=====================================================
//
//    cout << endl << "\t,请调整滚动条观察图像效果~\n\n"
//        << "\t按下“q”键时,程序退出~!";
//
//    while(char(waitKey(1))!='q'){}
//    return 0;
//}
//
//static void on_BoxFilter(int, void*)
//{
//    //方框滤波操作
//    boxFilter(g_srcImage, g_dstImage1, -1, Size(g_nBoxFilterValue + 1, g_nBoxFilterValue + 1));
//    //显示窗口
//    imshow("【<1>方框滤波】", g_dstImage1);
//}
//static void on_MeanBlur(int, void*)
//{
//    //均值滤波
//    blur(g_srcImage, g_dstImage2, Size(g_nMeanBlurValue + 1, g_nMeanBlurValue + 1),Point(-1,-1));
//    //显示窗口
//    imshow("【<2>均值滤波】", g_dstImage2);
//}
//static void on_GaussianBlur(int, void*)
//{
//    //高斯滤波
//    GaussianBlur(g_srcImage, g_dstImage1, Size(g_nGaussianBlurValue*2 + 1, g_nGaussianBlurValue*2 + 1),0,0);
//    //显示窗口
//    imshow("【<3>高斯滤波】", g_dstImage3);
//}

/*-----------------------图像线性滤波综合示例 End---------------------------------*/

/*----------------------------高斯滤波GaussianBlur函数 Begin------------------------------*/

//int main()
//{
//    //载入原图
//    Mat image = imread("1.jpg");
//
//    //创建窗口
//    namedWindow("高斯滤波【原图】");
//    namedWindow("高斯滤波【效果图】");
//
//    //显示原图
//    imshow("高斯滤波【原图】", image);
//
//    //进行均值滤波
//    Mat out;
//    GaussianBlur(image, out, Size(7, 7),0,0);
//
//    //显示效果图
//    imshow("高斯滤波【效果图】", out);
//
//    waitKey(0);
//}

/*----------------------------高斯滤波GaussianBlur函数 End------------------------------*/

/*----------------------------均值滤波blur函数 Begin------------------------------*/

//int main()
//{
//    //载入原图
//    Mat image = imread("1.jpg");
//
//    //创建窗口
//    namedWindow("均值滤波【原图】");
//    namedWindow("均值滤波【效果图】");
//
//    //显示原图
//    imshow("均值滤波【原图】", image);
//
//    //进行均值滤波
//    Mat out;
//    blur(image, out, Size(7, 7));
//
//    //显示效果图
//    imshow("均值滤波【效果图】", out);
//
//    waitKey(0);
//}

/*----------------------------均值滤波blur函数 End------------------------------*/

/*----------------------------方框滤波boxFilter函数 Begin------------------------------*/

//int main()
//{
//    //载入原图
//    Mat image = imread("1.jpg");
//
//    //创建窗口
//    namedWindow("方框滤波【原图】");
//    namedWindow("方框滤波【效果图】");
//
//    //显示原图
//    imshow("方框滤波【原图】",image);
//
//    //进行方框滤波
//    Mat out;
//    boxFilter(image, out, -1, Size(7, 7));
//
//    //显示效果图
//    imshow("方框滤波【效果图】", out);
//
//    waitKey(0);
//}

/*----------------------------方框滤波boxFilter函数 End------------------------------*/

/*----------------XML和YAML文件的读取 Begin---------------------*/

//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;
//
//}

/*----------------XML和YAML文件的读取 End---------------------*/

/*------------------XML和YAML文件的写入 Begin-----------------------*/

//int main()
//{
//    //初始化
//    FileStorage fs("test.yaml", FileStorage::WRITE);
//
//    //开始文件写入
//    fs << "frameCount" << 5;
//    time_t rawtime;time(&rawtime);
//    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;
//        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("文件读写完毕,请在工程目录下查看生成的文件~");
//    getchar();
//    return 0;
//}

/*------------------XML和YAML文件的写入 End-----------------------*/

/*--------------------离散傅里叶变换 Begin--------------------*/

//int main()
//{
//    //以灰度模式读取原始图像并显示
//    Mat srcImage = imread("2.jpg", 0);
//    if (!srcImage.data)
//    {
//        printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~!\n");
//        return false;
//    }
//    imshow("原始图像", srcImage);
//    //ShowHelpText();
//
//    //将输入图像延扩到最佳的尺寸,边界用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));
//
//    //为傅里叶变换的结果(实部和虚部)分配存储空间
//    //将planes数组组合合并成一个多通道的数组complexI
//    Mat planes[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };
//    Mat complexI;
//    merge(planes, 2, complexI);
//
//    //进行就地离散傅里叶变换
//    dft(complexI, complexI);
//
//    //将复数转换为幅值,即=>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];
//
//    //进行对数尺度(logarithmic scale)缩放
//    magnitudeImage += Scalar::all(1);
//    log(magnitudeImage, magnitudeImage);//求自然对数
//
//    //剪切和重分布幅度图象限
//    //若有奇数行或奇数列,进行频谱裁剪
//    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);
//
//    //归一化,用0到1之间的浮点数将矩阵变换为可视的图像格式
//    normalize(magnitudeImage, magnitudeImage, 0, 1, CV_MINMAX);
//
//    //显示效果图
//    imshow("频谱幅值", magnitudeImage);
//    waitKey();
//    return 0;
//}

/*--------------------离散傅里叶变换 End--------------------*/

/*-------------图像对比度、亮度调整   Begin--------------*/

//static void on_ContrastAndBright(int, void*);
//static void ShowHelpText();
//
//int g_nContrastValue;
//int g_nBrightValue;
//Mat g_srcImage, g_dstImage;
//
//int main()
//{
//    g_srcImage = imread("1.jpg");
//    if (!g_srcImage.data)
//    {
//        printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~!");
//        return false;
//    }
//    g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());
//
//    g_nContrastValue = 80;
//    g_nBrightValue = 80;
//
//    namedWindow("【效果图窗口】", 1);
//
//    //创建轨迹条
//    createTrackbar("对比度:", "【效果图窗口】", &g_nContrastValue, 300, on_ContrastAndBright);
//    createTrackbar("亮度:", "【效果图窗口】", &g_nBrightValue, 200, on_ContrastAndBright);
//
//    //进行回调函数初始化
//    on_ContrastAndBright(g_nContrastValue, 0);
//    on_ContrastAndBright(g_nBrightValue, 0);
//
//    while(char(waitKey(1))!='q'){}
//    return 0;
//}
//
//static void on_ContrastAndBright(int, void*)
//{
//    namedWindow("【原始图窗口】", 1);
//    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);
//}

/*-------------图像对比度、亮度调整  End--------------*/

/*split()函数用于将一个多通道数组分离成几个单通道数组*/
//vector<Mat> channels;
//Mat imageBlueChannel;
//Mat imageGreenChannel;
//Mat imageRedChannel;
//
//split(srcImage4, channels);
//imageBlueChannel = channels.at(0);
//imageGreenChannel = channels.at(1);
//imageRedChannel = channels.at(2);

/*merge()函数 将多个数组合并成一个多通道的数组*/
//Mat srcImage = imread("1.jpg");
//Mat imageBlueChannel, imageGreenChannel, imageRedChannel, mergeImage;
//vector<Mat> channels;
//split(srcImage, channels);
//imageBlueChannel = channels.at(0);
//imageGreenChannel = channels.at(1);
//imageRedChannel = channels.at(2);
//merge(channels, mergeImage);
//imshow("mergeImage", mergeImage);

/*RGB通道示例*/

//bool MultiChannelBlending();
//void ShowHelpText();
//
//int main()
//{
//    system("color 9F");
//    if (MultiChannelBlending())
//    {
//        cout << endl << "\n运行成功,得出了需要的图像~!";
//    }
//    waitKey(0);
//    return 0;
//}
//bool MultiChannelBlending()
//{
//    Mat srcImage;
//    Mat logoImage;
//    vector<Mat> channels;
//
//    Mat imageBlueChannel;
//    logoImage = imread("2.jpg", 0);
//    srcImage = imread("1.jpg");
//    if (!logoImage.data)
//    {
//        printf("读取logoImage错误~!\n");
//        return false;
//    }
//    if (!srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//    split(srcImage, channels);
//    imageBlueChannel = channels.at(0);
//    addWeighted(imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)),1.0,logoImage,0.5,0,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)));
//    merge(channels, srcImage);
//    namedWindow("游戏原画+logo蓝色通道");
//    imshow("游戏原画+logo蓝色通道", srcImage);
//
//
//    Mat imageGreenChannel;
//    logoImage = imread("2.jpg", 0);
//    srcImage = imread("1.jpg");
//    if (!logoImage.data)
//    {
//        printf("读取logoImage错误~!\n");
//        return false;
//    }
//    if (!srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//    split(srcImage, channels);
//    imageGreenChannel = channels.at(1);
//    addWeighted(imageGreenChannel(Rect(500, 250, logoImage.cols, logoImage.rows)), 1.0, logoImage, 0.5, 0, imageGreenChannel(Rect(500, 250, logoImage.cols, logoImage.rows)));
//    merge(channels, srcImage);
//    namedWindow("游戏原画+logo绿色通道");
//    imshow("游戏原画+logo绿色通道", srcImage);
//
//
//    Mat imageRedChannel;
//    logoImage = imread("2.jpg", 0);
//    srcImage = imread("1.jpg");
//    if (!logoImage.data)
//    {
//        printf("读取logoImage错误~!\n");
//        return false;
//    }
//    if (!srcImage.data)
//    {
//        printf("读取srcImage错误~!\n");
//        return false;
//    }
//    split(srcImage, channels);
//    imageRedChannel = channels.at(2);
//    addWeighted(imageRedChannel(Rect(500, 250, logoImage.cols, logoImage.rows)), 1.0, logoImage, 0.5, 0, imageRedChannel(Rect(500, 250, logoImage.cols, logoImage.rows)));
//    merge(channels, srcImage);
//    namedWindow("游戏原画+logo红色通道");
//    imshow("游戏原画+logo红色通道", srcImage);
//
//    return true;
//}

/*初级图像混合*/
//bool ROI_AddImage();
//bool LinearBlending();
//bool ROI_LinearBlending();
//
//int main()
//{
//    system("color 5E");
//    if (ROI_AddImage() && LinearBlending() && ROI_LinearBlending())
//    {
//        cout << endl << "运行成功,得出了你需要的图像~!:";
//    }
//    waitKey(0);
//    return 0;
//}
//
//bool ROI_AddImage()
//{
//    Mat srcImage1 = imread("1.jpg");
//    Mat logoImage = imread("2.jpg");
//
//    if (!srcImage1.data)
//    {
//        printf("读取srcImage1错误~!\n");
//        return false;
//    }
//    if (!logoImage.data)
//    {
//        printf("读取logoImage错误~!\n");
//        return false;
//    }
//    Mat imageROI;
//    imageROI = srcImage1(Rect(200, 250, logoImage.cols, logoImage.rows));
//    //加载掩模(必须是灰度图)
//    Mat mask = imread("2.jpg", 0);
//    logoImage.copyTo(imageROI, mask);
//    namedWindow("利用ROI实现图像叠加示例窗口");
//    imshow("利用ROI实现图像叠加示例窗口", srcImage1);
//    return true;
//}
//
//bool LinearBlending()
//{
//    double alphaValue = 0.5;
//    double betaValue;
//    Mat srcImage2, srcImage3, dstImage;
//
//    srcImage2 = imread("3.jpg");
//    srcImage3 = imread("4.jpg");
//    if (!srcImage2.data)
//    {
//        printf("读取srcImage2错误~!\n");
//        return false;
//    }
//    if (!srcImage3.data)
//    {
//        printf("读取srcImage3错误~!\n");
//        return false;
//    }
//
//    betaValue = (1.0 - alphaValue);
//    addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);
//
//    namedWindow("线性混合示例窗口【原图】", 1);
//    imshow("线性混合示例窗口【原图】", srcImage2);
//    namedWindow("线性混合示例窗口【效果图】", 1);
//    imshow("线性混合示例窗口【效果图】", dstImage);
//
//    return true;
//}
//
//bool ROI_LinearBlending()
//{
//    Mat srcImage4 = imread("1.jpg", 1);
//    Mat logoImage = imread("2.jpg");
//
//    if (!srcImage4.data)
//    {
//        printf("读取srcImage4错误~!\n");
//        return false;
//    }
//    if (!logoImage.data)
//    {
//        printf("读取logoImage错误~!\n");
//        return false;
//    }
//
//    Mat imageROI;
//    imageROI = srcImage4(Rect(200, 250, logoImage.cols, logoImage.rows));
//    addWeighted(imageROI, 0.5, logoImage, 0.3, 0., imageROI);
//
//    namedWindow("区域线性图像混合示例窗口");
//    imshow("区域线性图像混合示例窗口", srcImage4);
//
//    return true;
//}

/*绘制函数*/
//#define WINDOW_NAME1 "【绘制图1】"
//#define WINDOW_NAME2 "【绘制图2】"
//#define WINDOW_WIDTH 600
//void DrawEllipse(Mat img, double angle)
//{
//    int thickness = 2;
//    int lineType = 8;
//
//    ellipse(img,
//        Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2),
//        Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16),
//        angle,
//        0,
//        360,
//        Scalar(255, 129, 0),
//        thickness,
//        lineType
//    );
//}
//void DrawFilledCircle(Mat img, Point center)
//{
//    int thickness = -1;
//    int lineType = 8;
//    circle(img,
//        center,
//        WINDOW_WIDTH / 32,
//        Scalar(0, 0, 255),
//        thickness,
//        lineType
//    );
//}
//void DrawPolygon(Mat img)
//{
//    int lineType = 8;
//    Point rookPoints[1][20];
//    rookPoints[0][0] = Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
//    rookPoints[0][1] = Point(3*WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
//    rookPoints[0][2] = Point(3*WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);
//    rookPoints[0][3] = Point(11*WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);
//    rookPoints[0][4] = Point(19*WINDOW_WIDTH / 32, 7 * WINDOW_WIDTH / 8);
//    rookPoints[0][5] = Point(3*WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);
//    rookPoints[0][6] = Point(3*WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);
//    rookPoints[0][7] = Point(26*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 8);
//    rookPoints[0][8] = Point(26*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 4);
//    rookPoints[0][9] = Point(22*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 4);
//    rookPoints[0][10] = Point(22*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 8);
//    rookPoints[0][11] = Point(18*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 8);
//    rookPoints[0][12] = Point(18*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 4);
//    rookPoints[0][13] = Point(14*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 4);
//    rookPoints[0][14] = Point(14*WINDOW_WIDTH / 40,  WINDOW_WIDTH / 8);
//    rookPoints[0][15] = Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
//    rookPoints[0][16] = Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
//    rookPoints[0][17] = Point(13*WINDOW_WIDTH / 32, 7 * WINDOW_WIDTH / 8);
//    rookPoints[0][18] = Point(5*WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);
//    rookPoints[0][19] = Point( WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);
//
//    const Point* ppt[1] = { rookPoints[0] };
//    int npt[] = { 20 };
//
//    fillPoly(img,
//        ppt,
//        npt,
//        1,
//        Scalar(255, 255, 255),
//        lineType);
//}
//void DrawLine(Mat img, Point start, Point end)
//{
//    int thickness = 2;
//    int lineType = 8;
//    line(img,
//        start,
//        end,
//        Scalar(0, 0, 0),
//        thickness,
//        lineType);
//}
//
//int main(void)
//{
//    //创建空白的Mat图像
//    Mat atomImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
//    Mat rookImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
//
//    DrawEllipse(atomImage, 90);
//    DrawEllipse(atomImage, 0);
//    DrawEllipse(atomImage, 45);
//    DrawEllipse(atomImage, -45);
//
//    DrawFilledCircle(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2));
//
//    DrawPolygon(rookImage);
//    
//    rectangle(rookImage,
//        Point(0, 7 * WINDOW_WIDTH / 8),
//        Point(WINDOW_WIDTH, WINDOW_WIDTH),
//        Scalar(0, 255, 255),
//        -1,
//        8);
//
//    DrawLine(rookImage,
//        Point(0, 15 * WINDOW_WIDTH / 16),
//        Point(WINDOW_WIDTH, 15 * WINDOW_WIDTH / 16));
//    DrawLine(rookImage,
//        Point(WINDOW_WIDTH/4, 7 * WINDOW_WIDTH / 8),
//        Point(WINDOW_WIDTH/4, WINDOW_WIDTH));
//    DrawLine(rookImage,
//        Point(WINDOW_WIDTH/2, 7 * WINDOW_WIDTH / 8),
//        Point(WINDOW_WIDTH/2, WINDOW_WIDTH));
//    DrawLine(rookImage,
//        Point(3*WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8),
//        Point(3*WINDOW_WIDTH/4,WINDOW_WIDTH));
//
//    imshow(WINDOW_NAME1, atomImage);
//    moveWindow(WINDOW_NAME1, 0, 200);
//    imshow(WINDOW_NAME2, rookImage);
//    moveWindow(WINDOW_NAME2, WINDOW_WIDTH, 200);
//
//    waitKey(0);
//    return(0);
//
//}

/*常用数据结构*/
//int main()
//{    
//    /*1.Point类*/
//    Point point;
//    point.x = 10;
//    point.y = 8;
//    //Point point=Point(10,8);
//
//    /*2.Scalar类*/
//    Scalar(0, 0, 0);
//
//    /*Size类*/
//    Size(5, 5);
//
//    /*Rect类*/
//    //Rect(x,y,width,hight)左上角点的坐标和矩形的宽和高,成员函数Size()返回宽和高,area()返回矩形面积,
//    //contains(Point)判断点是否在矩形内,inside(Rect)函数判断矩形是否在该矩形内,tl()返回左上角的坐标,br()返回右下角坐标,
//    //求两个矩形的交集Rect rect=rect1&rect2;
//    //求两个矩形的交集Rect rect=rect1|rect2;
//    //矩形平移Rect rectshift=rect+point;
//    //矩形放缩Rect rectScale=rect+size;
//
//    /*cvtColor()函数,颜色空间转换*/
//    Mat srcImage, dstImage;
//    srcImage = imread("5.jpg");
//    cvtColor(srcImage, dstImage, CV_GRAY2BGR);
//    imshow("sss", dstImage);
//    waitKey();
//}

/*画矩形*/
//#define WINDOW_NAME "【程序窗口】"
//void on_MouseHandle(int event, int x, int y, int flags, void* param);
//void DrawRectangle(cv::Mat& img, cv::Rect box);
//void ShowHelpText();
//
//Rect g_rectangle;
//bool g_bDrawingBox = false;
//RNG g_rng(12345);
//
//int main(int argc, char** argv)
//{
//    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);
//
//    namedWindow(WINDOW_NAME);
//    setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
//    while (1)
//    {
//        srcImage.copyTo(tempImage);
//        if (g_bDrawingBox)
//        {
//            DrawRectangle(tempImage, g_rectangle);
//        }
//        imshow(WINDOW_NAME, tempImage);
//        if (waitKey(10) == 27)
//            break;
//    }
//    return 0;
//}
//void on_MouseHandle(int event, int x, int y, int flags, void* param)
//{
//    Mat& image = *(cv::Mat*) param;
//    switch (event)
//    {
//    case EVENT_MOUSEMOVE:
//    {
//        if (g_bDrawingBox)
//        {
//            g_rectangle.width = x - g_rectangle.x;
//            g_rectangle.height = y - g_rectangle.y;
//        }
//    }
//    break;
//    case EVENT_LBUTTONDOWN:
//    {
//        g_bDrawingBox = true;
//        g_rectangle = Rect(x, y, 0, 0);
//    }
//    break;
//    case EVENT_LBUTTONUP:
//    {
//        g_bDrawingBox = false;
//        if (g_rectangle.width < 0)
//        {
//            g_rectangle.x += g_rectangle.width;
//            g_rectangle.width *= -1;
//        }
//        if (g_rectangle.height < 0)
//        {
//            g_rectangle.y += g_rectangle.height;
//            g_rectangle.height *= -1;
//        }
//        DrawRectangle(image, g_rectangle);
//    }
//    break;
//    }
//}
//void DrawRectangle(cv::Mat& img, cv::Rect box)
//{
//    rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
//}

/*两幅图混合*/
//#define WINDOW_NAME "【线性混合示例】"
//
//const int g_nMaxAlphaValue = 100;
//int g_nAlphaValueSlider;
//double g_dAlphaValue;
//double g_dBetaValue;
//
//Mat g_srcImage1;
//Mat g_srcImage2;
//Mat g_dstImage;
//
//void on_Trackbar(int, void*)
//{
//    g_dAlphaValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
//    g_dBetaValue = (1.0 - g_dAlphaValue);
//    addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
//    imshow(WINDOW_NAME, g_dstImage);
//}
//
//int main(int argc,char** argv)
//{
//    g_srcImage1 = imread("1.jpg");
//    g_srcImage2 = imread("2.jpg");
//    if (!g_srcImage1.data)
//    {
//        printf("读取第一幅图片错误,请确定目录下是否有imread函数指定图片存在~!\n");
//        return - 1;
//    }
//    if (!g_srcImage2.data)
//    {
//        printf("读取第二幅图片错误,请确定目录下是否有imread函数指定图片存在~!\n");
//        return -1;
//    }
//
//    //设置滑动条初值为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);
//    return 0;
//}

/*2.2综合示例程序:图像的载入、显示与输出*/

//int main()
//{
//    Mat picture1 = imread("1.jpg");
//    namedWindow("图片1");
//    imshow("图片1",picture1);
//
//    Mat image = imread("2.jpg", 199);
//    Mat image1 = imread("3.jpg");
//    namedWindow("图片2");
//    imshow("图片2", image);
//    namedWindow("图片3");
//    imshow("图片3", image1);
//
//    Mat imageROI;
//    imageROI = image(Range(350, 350+image1.cols),Range(400,400+image1.cols));//报错
//    addWeighted(imageROI, 0.5, image1, 0.3, 0., imageROI);
//    namedWindow("图片4");
//    imshow("图片4", image);
//    imwrite("由imwrite生成的图片.jpg", image);
//    waitKey();
//    return 0;
//}

/*2.1在openCV中生成衣服png图片,并写入到当前工程目录下*/
void createAlphaMat(Mat &mat)
{
    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]));
        }
    }
}

int main()
{
    //创建带Alpha通道的Mat
    Mat mat(480, 640, CV_8UC4);
    createAlphaMat(mat);

vector<int>compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);
    try {
        imwrite("透明Alpha值图.png", mat, compression_params);
        imshow("生成的PNG图", mat);
        fprintf(stdout, "PNG图片文件的alpha数据保存完毕~\n可以在工程目录下查看由imwrite函数生成的图片\n");
        waitKey(0);
    }
    catch (runtime_error& ex)
    {
        fprintf(stderr, "图像转换成PNG格式发生错误:%s\n", ex.what());
        return 1;
    }
    return 0;
}

//#1   pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
/*第一章练习
int main()
{
    /**
    const char* pstrImageName = "1.jpg";
    const char* pstrWindowsTitle = "OpenCV第一个程序";

//从文件中读取图像
    IplImage* pImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);

//创建窗口
    cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE);

//在指定窗口中显示图像
    cvShowImage(pstrWindowsTitle, pImage);

//等待按键事件
    cvWaitKey();

cvDestroyWindow(pstrWindowsTitle);
    cvReleaseImage(&pImage);
    return 0;
    **/

/*
    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);
    return 0;
    */

/*
    Mat srcImage = imread("1.jpg");
    imshow("均值滤波", srcImage);

Mat dstImage;
    blur(srcImage, dstImage, Size(7, 7));
    imshow("均值滤波效果图", dstImage);
    waitKey(0);
    return 0;
    */

/*
    Mat srcImage = imread("1.jpg");
    imshow("Canny边缘检测", srcImage);
    Mat edge, grayImage;
    cvtColor(srcImage, grayImage, CV_BGR2GRAY);
    blur(grayImage,edge, Size(3, 3));
    Canny(edge, edge, 3, 9, 3);
    imshow("Canny边缘检测", edge);
    waitKey(0);
    return 0;
    */

/*
    VideoCapture capture;
    capture.open("1.avi");
    while (1)
    {
        Mat frame;
        capture >> frame;
        if (frame.empty())
        {
            break;
        }
        imshow("读取视频", frame);
        waitKey(30);
    }
    return 0;
    */

/*
    VideoCapture capture;
    capture.open(0);
    while (1)
    {
        Mat frame;
        capture >> frame;
        imshow("读取视频", frame);
        waitKey(30);
    }
    return 0;
    */

/*
    VideoCapture capture("1.avi");
    Mat edges;

while (1)
    {
        Mat frame;
        capture >> frame;
        cvtColor(frame, edges, CV_BGR2GRAY);
        blur(edges, edges, Size(7, 7));
        Canny(edges, edges, 0, 30, 3);
        imshow("被Canny后的视频", edges);
        if (waitKey(30) >= 0) break;
    }
    return 0;
}*/

OpenCV3编程入门(一)相关推荐

  1. OpenCV3编程入门(毛星云)之用滚动条控制两图片的混合

    OpenCV3编程入门书本上的示例,copy下来学习学习~~代码如下: 美女1 美女2 #include <opencv2/opencv.hpp> using namespace cv; ...

  2. OpenCV3编程入门(毛星云)之视频读取与播放

    OpenCV3编程入门(毛星云)之视频读取与播放,看看运行截图: 看来OpenCV API封装得太好了..努力,努力,再努力~~~

  3. Opencv3编程入门学习笔记(五)之通道分离(split)与合并(merge)

    若要对Opencv中(BGR)颜色通道进行单一处理,那必然会涉及到通道分离(split)与合并(merge).那么本篇博客笔者记录了两个方法的使用方法和案例.案例来源于<Opencv3编程入门学 ...

  4. Opencv3编程入门学习笔记(四)之split通道分离Debug过程中0xC0000005内存访问冲突问题

    这是笔者学习<Opencv3编程入门>的第四篇博客,这篇博客主要是解决在Windows系统下VS 2013中Debug含有split分离通道色彩函数时报出的0xC0000005内存访问冲突 ...

  5. Opencv3编程入门学习笔记(三)之访问图像像素的三种方法

    访问图像像素的三种方法:指针访问,迭代器访问,动态地址访问.访问最快的为指针访问,以下算法在几毫秒,但指针访问容易造成内存泄漏:其次为迭代器访问:最后为动态地址访问. 以下程序是根据<OpenC ...

  6. Opencv3编程入门学习笔记(二)之显式创建Mat对象

    以下总结是基于<Opencv3编程入门>一书4.1节总结的内容进行验证与总结,验证环境均为Windows10 ---VS2013 C++环境,验证Opencv3.0提供的开发包. 1. 方 ...

  7. 【浅墨著作】 OpenCV3编程入门 内容简介 勘误 配套源代码下载

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 经过近一 ...

  8. 【OpenCV学习】 《OpenCV3编程入门》--毛星云 01 邂逅OpenCV(OpenCV基本概念与基本架构) ROS系统上的运用(python实现)

    对 <OpenCV3编程入门>第一章的学习笔记:理解什么是计算机视觉,什么是OpenCV,以及其中的联系等等. PS:此书为2014年出版,opencv的版本和接口也与现在有些不一致了,作 ...

  9. 图像识别(2)——《OpenCV3编程入门》毛星云编著

    博主QQ:1356438802 QQ群:473383394--UVC&OpenCV47 最近几天开始收集图像识别的相关资料: 程序开源库主要就是OpenCV,这是主流工具,所以我暂时也没去了解 ...

  10. 【资源】OpenCV3编程入门_毛星云

    OpenCV在计算机视觉领域扮演着重要的角色.作为一个基于开源发行的跨平台计算机视觉库,OpenCV实现了图像处理和计算机视觉方面的很多通用算法.<OpenCV3编程入门>以当前最新版本的 ...

最新文章

  1. [WebService] xml WebService学习1
  2. smbus使用 树莓派_树莓派学习笔记——I2C使用 PCF8574 Python SMBUS
  3. php下载文件代码 数据库,PHP备份数据库生成SQL文件并下载的函数代码
  4. 大数据行业到底有多少种工作岗位,各自的技能需求是什么?
  5. 360 回应安全云盘出现交易异常;苹果官网陆续限购 iPhone;GitHub 屏蔽微软工程师的开源项目 | 极客头条...
  6. 基于Linux平台Softimage XSI 演示
  7. 决策树、随机森林及代码实战
  8. Android应用调用第三方地图应用导航
  9. 百度网盘怎么取消自动续费
  10. ubuntu桌面便签_在Deepin 20、Ubuntu 20.04中安装便签小工具Stickynotes
  11. C++初阶学习————二叉树进阶(二叉搜索树)
  12. 打字游戏(极简单)——C/C++
  13. DTOJ 1552:网络小说分组(novel)
  14. 【过滤器和拦截器有什么区别】
  15. ZigBee Zstack之RSSI信号值获取以及显示
  16. 推送中的消息和通知的区别
  17. 1994-1999年考研数学二真题及其详解
  18. EffectiveC++-条款51:编写 new 和 delete 时需固守常规
  19. textmate常用快捷键备忘
  20. 微信小程序公众号开发

热门文章

  1. SAP 消耗型采购科目确定(一)
  2. SQLMAP 实例COOKBOOK
  3. 快手的推广方法以及引流技巧
  4. muduo如何从0到1
  5. 学画画要花多少钱_高考学画画要花多少钱
  6. 什么是项目管理系统?
  7. java 耗时 框架_真真香!耗时大半个月收整全套「Java架构进阶pdf」没白费
  8. 解决git问题:fatal: Need to specify how to reconcile divergent branches.
  9. 如何使用清源CleanSource SCA建立软件物料清单(SBOM)
  10. item_search_best-天猫畅销榜API接入详情说明