opencv/c++图像处理未完待续

图像二值化处理

namedWindow

namedWindow():新建一个显示窗口。可以指定窗口的类型。
参数一:窗口名称
参数二:窗口标识。默认为WINDOW_AUTOSIZE。
WINDOW_AUTOSIZE:窗口大小自动适应图片大小,并且不可手动更改。
WINDOW_NORMAL:用户可以改变这个窗口大小。
WINDOW_OPENGL:窗口创建的时候会支持OpenGL。

imread

imread():载入一张图片。该函数经常配合imshow( )函数一起使用。

imshow

imshow( ):函数功能就是把你刚才载入的图片显示出来。

waitKey

等待按键事件

Mat

data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存 (uchar* data)

dims:Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维

channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。

depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;

step:是一个数组,定义了矩阵的布局,具体见下面图片分析,另外注意 step1 (step / elemSize1),M.step[m-1] 总是等于 elemSize,M.step1(m-1)总是等于 channels;

elemSize : 矩阵中每一个元素的数据大小,如果Mat中的数据的数据类型是 CV_8U 那么 elemSize = 1,CV_8UC3 那么 elemSize = 3,CV_16UC2 那么 elemSize = 4;记住另外有个 elemSize1 表示的是矩阵中数据类型的大小,即 elemSize / channels 的大小

void two() {    
    //定义变量
    Mat img;
    int threshval = 170;//设定阈值
    Mat result;
    Mat bw = img;
    //载入图片
    img = imread("D:\\in.jpg", 0);
    //显示原图 
    namedWindow("原始图像");
    imshow("原始图像", img);
    bw = threshval < 100 ? (img < 160) : (img > 160);//如果阈值小于100,那么中间为真,即像素值小于160的为1,大于160的为0;如果阈值大于100,那么右边为真,即像素值大于160的为1,小于160的为0.
    namedWindow("二值化后的图像");
    imshow("二值化后的图像", bw);
    waitKey(0);
}

图像轮廓提取

cvtcolor():函数是一个颜色空间转换函数,可以实现RGB颜色向HSV,HSI等颜色空间转换。也可以转换为灰度图。

findContours函数介绍

void line() {	
    Mat img, dst;	
    img = imread("D:\\in.jpg");	
    namedWindow("原始图像", CV_WINDOW_AUTOSIZE);	
    imshow("原始图像", img);	
    dst = Mat::zeros(img.size(), CV_8UC3);//相当于创建一张黑色的图  	
    blur(img, img, Size(3, 3));  //用标准化的盒式过滤器来平滑图像	
    cvtColor(img, img, COLOR_BGR2GRAY);//颜色转换	
    Canny(img, img, 20, 80, 3, false);  //使用canny算法对输入图像进行边缘检测
    std::vector<std::vector<Point>> contours; //是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。有多少轮廓,向量contours就有多少元素。	
    std::vector<Vec4i> hierarchy;  //Vec4i是Vec<int,4>的别名,定义了一个“向量内每一个元素包含了4个int型变量”的向量。	
    findContours(img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//检测出物体的轮廓 	
    RNG rng(0);    //随机生成数	
    for (int i = 0; i < contours.size(); i++)	{		
        Scalar color = Scalar(rng.uniform(255, 255), rng.uniform(255, 255), rng.uniform(255, 255));//将图像设置成单一灰度和颜色		
        drawContours(dst, contours, i, color, 1, 8, hierarchy, 0, Point(0, 0));    //用于画出图像的轮廓	
    }	
    namedWindow("轮廓", CV_WINDOW_AUTOSIZE);	imshow("轮廓", dst);
    waitKey(0);
}

计算图像梯度

Sobel函数

GaussianBlur函数参数详解如下:

src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。

dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。

ksize,高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数(并不能理解)。或者,它们可以是零的,它们都是由sigma计算而来。

sigmaX,表示高斯核函数在X方向的的标准偏差。

sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。为了结果的正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。

borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

在这里插入图片描述
该操作可实现图像增强等相关操作的快速运算

void gradient() {	
    Mat src, gray, dst;	
    src = imread("D:\\in.jpg");	
    namedWindow("input", CV_WINDOW_AUTOSIZE);	
    imshow("input", src);	
    GaussianBlur(src, src, Size(3, 3), 0, 0); //进行均值滤波操作
    cvtColor(src, gray, CV_BGR2GRAY);  //转换为灰度图
    //【1】sobel算子	
    Mat gradient_x, gradient_y;	
    Sobel(gray, gradient_x, CV_16S, 1, 0, 3);	
    Sobel(gray, gradient_y, CV_16S, 0, 1, 3); 	
    //【2】Scharr算子	
    //Scharr(gray, gradient_x, CV_16S, 1, 0, 1, 0);
    //Scharr(gray, gradient_y, CV_16S, 1, 0, 1, 0);*/
    //计算绝对值	
    convertScaleAbs(gradient_x, gradient_x);	
    convertScaleAbs(gradient_y, gradient_y);	
    //imshow("gradient_x", gradient_x);	
    //imshow("gradient_y", gradient_y);	
    addWeighted(gradient_x, 1, gradient_y, 1, 0, dst); 	
    //【3】laplace算子	
    //Laplacian(gray, dst, CV_16S, 3);	
    //convertScaleAbs(dst, dst); 	
    //通过访问像素进行操作 	
    int rows = gradient_x.rows; 	
    int cols = gradient_x.cols; 	
    Mat dst1 = Mat::zeros(gradient_x.size(), gradient_x.type()); 	
    for (int i = 0; i < rows; i++) { 		
        for (int j = 0; j < cols; j++) { 			
            dst1.at<uchar>(i, j) = saturate_cast<uchar>(gradient_x.at<uchar>(i, j) + gradient_y.at<uchar>(i, j));  //防止数据溢出 		
        } 	
    } 	
    imshow("梯度", dst1);	
    waitKey(0);
}
发布了35 篇原创文章 · 获赞 2 · 访问量 958

猜你喜欢

转载自blog.csdn.net/y18771025420/article/details/103384675
今日推荐