美文网首页
004 图像像素的读写操作

004 图像像素的读写操作

作者: 几时见得清梦 | 来源:发表于2019-07-25 07:22 被阅读0次
    • 本节内容:图像像素操作:遍历与访问

    C++

    在C++中访问OpenCV Mat对象每个像素点的像素值有两种方式:

    1. 通过数组,逐个访问每个像素点的每个通道;
    2. 通过指针访问数组的像素点的地址,然后从地址中取像素值 ---- 效率更高;
    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
    int main(int artc, char** argv) {
        Mat src = imread("D:/vcprojects/images/test.png");
        if (src.empty()) {
            printf("could not load image...\n");
            return -1;
        }
        namedWindow("input", CV_WINDOW_AUTOSIZE);
        imshow("input", src);
    
        // 直接读取图像像素:遍历访问,速度慢
        int height = src.rows; //读取图像高、宽、通道数
        int width = src.cols;
        int ch = src.channels(); //通道为3则为彩色图像,每个像素点有三个值;通道为1则为黑白图像,每个像素点有一个值。另外还有四通道图,为透明通道,若alpha=0则完全透明,alpha=255则完全不透明。
        for (int c = 0; c < ch; c++) {
            for (int row = 0; row < height; row++) {
                for (int col = 0; col < width; col++) {
                    if (ch == 3) {
                        Vec3b bgr = src.at<Vec3b>(row, col);//Vec3b是一个数据结构;Mat.at<Vec3b>(row, col)表示获取Mat在(row,col)位置的三个字节类型的值,存入Vec3b数据结构中
                        bgr[0] = 255 - bgr[0];//实现图像色彩取反。像素值范围为[0,255]
                        bgr[1] = 255 - bgr[1];
                        bgr[2] = 255 - bgr[2];
                        src.at<Vec3b>(row, col) = bgr; //对原像素点赋取反后的值
                    } else if(ch == 1) {
                        int gray = src.at<uchar>(row, col);
                        src.at<uchar>(row, col) = 255 - gray;
                    }
                }
            }
        }
        imshow("output", src);
    
        // 指针读取。代码展示了如何通过指针将原像素拷贝到另外一个Mat对象中。
        Mat result = Mat::zeros(src.size(), src.type()); //创建空白图像
        int blue = 0, green = 0, red = 0;
        int gray;
        for (int c = 0; c < ch; c++) {
            for (int row = 0; row < height; row++) {
                uchar* curr_row = src.ptr<uchar>(row);//Mat.ptr<uchar>(row)的作用是获取这一行所有像素点的像素块的首地址
                uchar* result_row = result.ptr<uchar>(row);//得到要输出的那一行的地址
                for (int col = 0; col < width; col++) { //对每一列遍历
                    if (ch == 3) { //对于三通道图像,列数*3是像素块的遍历次数
                        blue = *curr_row++;
                        green = *curr_row++;
                        red = *curr_row++;
    
                        *result_row++ = blue;
                        *result_row++ = green;
                        *result_row++ = red;
                    }
                    else if (ch == 1) {
                        gray = *curr_row++;
                        *result_row++ = gray;
                    }
                }
            }
        }
        imshow("result", result);
    
        waitKey(0);
        return 0;
    }
    

    Python

    import cv2 as cv
    
    src = cv.imread("D:/vcprojects/images/test.png")
    cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
    cv.imshow("input", src)
    h, w, ch = src.shape #获取图像高、宽、通道数。如果图像为灰度图,则img.shape只会返回h和w
    print("h , w, ch", h, w, ch)
    for row in range(h): #横向和纵向都是从0开始索引
        for col in range(w):
            b, g, r = src[row, col] #直接读取到三个通道的值
            b = 255 - b
            g = 255 - g
            r = 255 - r
            src[row, col] = [b, g, r] #将原图像上的对应像素取反
    cv.imshow("output", src)
    
    cv.waitKey(0)
    cv.destroyAllWindows()
    

    相关文章

      网友评论

          本文标题:004 图像像素的读写操作

          本文链接:https://www.haomeiwen.com/subject/olbqrctx.html