OpenCV学习:基础图像操作 (一):打开、显示、保存图像,用像素指针访问图像像素

1.打开图像,创建窗口,显示图片,保存图片

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
int main(int argc, char** argv)
{    
    // 打开图片
    // 第一个参数为文件名  第二个参数为图像是什么类型
    //
    //   # <0   IMREAD_UNCHAGED  不做改变
    //   # =0  IMREADER_GRAYSCALE 灰度图像
    //   # >0  IMREAD_COLOR  读入为RGB
    Mat src = imread("1.jpg");
    //判断图片是否成功打开

    //修改颜色空间 cvtColor 
    // 原图  保存图   转换格式
    //
    cvtColor(src,gray_image,COLOR_BGR2GRAY);

    if(src.empty())
    {
        printf("打开图片不存在!");
        return -1;
    }
     
    //创建窗口  窗口名称 字符串  窗口类型
    //         #0   CV_WINDOW_AUTOSIZE 初始化时自适应图片,但用户不可改变
    //         #1   WINDOW_NORMAL   窗口大小自适应图片,但可改变大小 调用QT
    //         #2   WINDOW_OPENGL   窗口创建的时候会支持OpenGL
    nameWindow("TEST OPENCV",CV_WINDOW_AUTOSIZE);
    //删除窗口时,可以使用destroyWindow()或者destoryALLWindows()
    

    //显示图片 窗口名称  图片矩阵
    imshow("EST OPENCV",src);

    //设置图片刷新到 屏幕的时间  返回值为当前键盘按键值
    //不断刷新图像,频率时间为delay,单位为ms
    /*
        delay>0时,延迟”delay”ms,在显示视频时这个函数是有用的,用于设置在显示完一帧图像后程序
        等待”delay”ms再显示下一帧视频;如果使用cvWaitKey(0)则只会显示第一帧视频。
        返回值:如果delay>0,那么超过指定时间则返回-1;如果delay=0,将没有返回值。
        如果程序想响应某个按键,可利用if(cvWaitKey(1)==Keyvalue); 
        经常程序里面出现if( cvWaitKey(10) >= 0 ) 是说10ms中按任意键进入此if块。
    */
    waitKey(0);
    //保存图像
    imwrite("gray",gray_image);
    return 0;
}

2.有关像素的操作

获取像素指针,用掩膜来提高对比度

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namesapce cv;
int main()
{
    Mat src,dst;
    src = imread("1.png",1);
    
    //用data来判断图片是否打开
    if(!src.data)
    {
        printf("无法打开图像");
        return -1;
    }
    


    //每一行 因为有三个通道所以 实际宽度要乘上通道数
    int cols = src.cols*src.channel();//把三维图像矩阵降维二位矩阵处理  
    int rows = src.rows;
    int offsetx = src.channels();

    // 掩膜操作 就是卷积了下面这个算子  来提高对比对度 
    //  0  -1  0
    //  -1  5  -1
    //  0   -1  0
    
    //创建零矩阵 形状大小与原图一样,类型也一样
    dst = Mat::zeros(src.size(),src.type());
    

    for(int row = 1; row < rows-1;row++)
    {
        //获取像素指针 每一行
        const uchar* previous = src.prt<uchar>(row-1);
        const uchar* current = src.prt<uchar>(row);
        const uchar* next = src.prt<uchar>(row+1);
        uchar* output =  dst.prt<uchar>(row);
        //遍历每一行,有三个通道所以两端隔三个像素
        for(int col = offsetx ;col < cols-offsetx;col++ )
        {
            output[col] = saturate_cast<uchar>(5 * current[col] - current[col-offsetx]-current[col+offsetx]-previous[col] - next[col]);
            //直接计算会有值一处[0,255],使用saturate_cast<uchar>来限制输出的范围
            //即比零小的设为零 比255大的设为255
        }
    }

    

    //使用filter2D来代替上述过程,
    
    //创建kernel 
    Mat kernel = (Mat_<uchar>(3,3) << 0,-1,0,-1,5,-1,0,-1,0);
    
    //记录运行时间
    double st =  getTickCount();


    //src.depth() 图像位深度,代表图像的存储的精度,有32,16,8等
    //            设为 -1 时,kernel会自适应
    filter2D(src,dst,src.depth(),kernel);

    double et =  getTickCount();
    double timecount = (et-st)/getTickFrequency();
    printf("time conunt %.2f",timecount);
    
    nameWindow("imput images",CV_WINDOW_AUTOSIZE);
    imshow("imput images",dst);

    waitKey(0);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fan1102958151/article/details/106910738