OpencCV之基础学习:图像的基本操作(一)---加载、修改、保存图像&读取修改像素值

根据自己在网课上的学习,记录一些笔记,加深记忆,在这里分享出来,大家一起学习,自己编程能力有限,对于一些专业名词的运用可能不太得当,不过希望能够让自己不断进步。如有不足不严谨之处希望大家指出来。

刚接触到opencv首先就是对图像进行一些操作

1.加载、修改、保存图像

(1)加载图像cv::mired

    利用Mat对象先创建一个对象,如命名为src,利用imread(“图像路径”,图像类型)加载图像;图像类型默认为1,其包含三种类型分别是IMREAD_GRAYSCALE(0)以灰度图类型加载图片、IMREAD_COLOR(>0)作为rgb图像加载进来,IMREAD_UNCHANGED(<0)作为原图加载进来。一般平常写程序时第二个参数都不填写。

    加载完图像后利用namedWindow函数创建一个窗口 namedWindow("窗口名",窗口类型) 。窗口类型一般我就选择两种,一种是cv_window_autosize,还有一种是cv_window_normal。第二种类型可以调整窗口大小。设置好窗口格式后,在显示图片,利用imshow("窗口名",src),本来应该与之前的那个函数一起使用的,但这个函数其实可以直接用,如果没有namedWindow来创建一个窗口,那么这个函数在找不到这个窗口名时,就可以自动生成一个窗口。第二个参数是加载进来的那个对象名。这样就可以加载一张图片了。

(2)修改图像cv::cvtColor

    cvtColor把图像从一个色彩空间转换成另一个色彩空间。cvtColor(src,dst,变换方案),src为源图像,dst为Mat新建的一个目标对象,变换方案就是对源图像做一些颜色变换,如变换成灰度图,既可以利用参数color_bgr2gray或者cv_gbr2gray,具体变换方案大家可以都尝试一下。

(3)保存图像cv::imwrite    

    imwrite("保存图像的路径", 待保存的对象)

演示代码:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, const char** argv) {
    // 加载图片
    Mat src=imread("/Users/Meng/Documents/cscpp/Pictures/test.png",IMREAD_UNCHANGED);
    if(src.empty()){//也可以用!src.data替换
        printf("could not load image..");
        return -1;
    }//显示图片
    namedWindow("test opencv setup",CV_WINDOW_NORMAL);
    imshow("test opencv setup",src);
    
    namedWindow("output window",WINDOW_AUTOSIZE);
    Mat output_image;
    cvtColor(src, output_image,CV_BGR2HLS);//修改图片
    
    imshow("output window", output_image);
    //保存图像
    imwrite("/Users/Meng/Documents/cscpp/Pictures/hlstest.png", output_image);
    
    waitKey(0);//wait for keyboard command
    return 0;
}

2.读写图片像素

图像有单通道和三通道之分,单通道就是灰度图像,黑白灰的那种,三通道就是rgb图像,彩色的那种。读取图像像素时对两种通道读取方式是不一样的。

(1)单通道:image.at<uchar>(x,y),单通道是uchar类型的,读取像素值比较容易

(2)三通道:image.at<Vec3b>(x,y)[index],多通道中需要除了填写类型和坐标外,还需要填写index值,即三个通道0、1、2,注意,这三个通道的顺序是b,g,r。即index=0对应的是blue,index=2对应red,这和我们平常说到RGB是反序的。其次,Vec3b是uchar类型数据,还有一种Vec3f是float类型,如果想转换成Vec3f,需要利用下述语句实现:

src.convertTo(src2, CV_32F);

下面展示一段代码,是反位操作,涉及到图像的像素指针的读取和修改。需要知道RGB像素值是0-255。

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

using namespace cv;
using namespace std;

int main(int argc, const char * argv[]) {
    Mat src,Gray_img,dst;
    src=imread("/Users/Meng/Documents/opencvTest/Pictures/qinxi.jpg");
    namedWindow("input",CV_WINDOW_NORMAL);
    imshow("input",src);
    cvtColor(src, Gray_img,CV_RGB2GRAY);
    //单通道
//    int rows=Gray_img.rows;
//    int cols=Gray_img.cols;
//    for(int row=0;row<=rows;row++){
//        for(int col=0;col<=cols;col++)
//        {
//            int g=Gray_img.at<uchar>(row,col);
//            Gray_img.at<uchar>(row,col)=255-g;
//        }
//    }
    //多通道
    dst.create(src.size(),src.type());
    int rows=src.rows;
    int cols=src.cols;

    for(int row=0;row<=rows;row++){
        for(int col=0;col<=cols;col++)
        {
            int b=src.at<Vec3f>(row,col)[0];
            int g=src.at<Vec3f>(row,col)[1];
            int r=src.at<Vec3f>(row,col)[2];
            dst.at<Vec3f>(row,col)[0]=255-b;
            dst.at<Vec3f>(row,col)[1]=255-g;
            dst.at<Vec3f>(row,col)[2]=255-r;
        }
    }
    //取反操作
    //bitwise_not(src, dst);
    
    namedWindow("output",CV_WINDOW_NORMAL);
    imshow("output", dst);
    waitKey(0);
    
}
大家可以注意到,其中倒数第四行代码是直接一步可以对图像进行取反的。


好啦,今天写到这里吧,加油!

    


猜你喜欢

转载自blog.csdn.net/z714977076/article/details/80461906