美文网首页
005 图像像素的算术操作

005 图像像素的算术操作

作者: 几时见得清梦 | 来源:发表于2019-07-25 07:51 被阅读0次
    • 本节内容:像素的加减乘除
    1. 两幅图像进行加减乘除时,图像类型、通道数、大小必须都一致。

    C++

    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
    int main(int artc, char** argv) {
        Mat src1 = imread("D:/vcprojects/images/LinuxLogo.jpg");
        Mat src2 = imread("D:/vcprojects/images/WindowsLogo.jpg");
        if (src1.empty() || src2.empty()) {
            printf("could not load image...\n");
            return -1;
        }
        namedWindow("input", CV_WINDOW_AUTOSIZE);
        imshow("input1", src1);
        imshow("input2", src2);
        int height = src1.rows;
        int width = src1.cols;
    
        int b1 = 0, g1 = 0, r1 = 0;
        int b2 = 0, g2 = 0, r2 = 0;
        int b = 0, g = 0, r = 0;
        
        //自己实现加减乘除
        Mat result = Mat::zeros(src1.size(), src1.type());
        for (int row = 0; row < height; row++) {
            for (int col = 0; col < width; col++) {
                    b1 = src1.at<Vec3b>(row, col)[0];//读出来是int类型
                    g1 = src1.at<Vec3b>(row, col)[1];
                    r1 = src1.at<Vec3b>(row, col)[2];
    
                    b2 = src2.at<Vec3b>(row, col)[0];
                    g2 = src2.at<Vec3b>(row, col)[1];
                    r2 = src2.at<Vec3b>(row, col)[2];
    
    
    //saturate_cast是C++函数,功能是实现精准的数据转型操作(损失很少精度,转型必然损失精度),如int转cchar、short转long等。建议对像素值转型时使用此函数。
    //为什么要对像素值转型为uchar类型:读出来的b1和b2都是int型,若相加后不转型则可能大于255、相减后不转型可能大于0。RGB的像素值范围是[0,255],不转型的话,无法用一个字节表示,会导致溢出。
    //saturate_cast的作用:大于255时截断高位保留低位,认为是255;小于0时认为是0。
                    result.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 + b2);
                    result.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 + g2);//uchar是一个字节8位的
                    result.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 + r2);
            }
        }
        imshow("output", result);
    
    
        //调用OpenCV的API完成加减乘除
        Mat add_result = Mat::zeros(src1.size(), src1.type()); //创建空白图像
        add(src1, src2, add_result); //add有三个参数(第一张图,第二张图,相加结果)。有时add有第四个参数,是mask。
        imshow("add_result", add_result);
    
        Mat sub_result = Mat::zeros(src1.size(), src1.type());
        subtract(src1, src2, sub_result);
        imshow("sub_result", sub_result);
    
        Mat mul_result = Mat::zeros(src1.size(), src1.type());
        multiply(src1, src2, mul_result);
        imshow("mul_result", mul_result);
    
        Mat div_result = Mat::zeros(src1.size(), src1.type());
        divide(src1, src2, div_result);
        imshow("div_result", div_result);
        
        waitKey(0);
        return 0;
    }
    

    Python

    import cv2 as cv
    import numpy as np
    
    src1 = cv.imread("D:/vcprojects/images/LinuxLogo.jpg");
    src2 = cv.imread("D:/vcprojects/images/WindowsLogo.jpg");
    cv.imshow("input1", src1)
    cv.imshow("input2", src2)
    h, w, ch = src1.shape
    print("h , w, ch", h, w, ch)
    
    add_result = np.zeros(src1.shape, src1.dtype); # 创建全0图像,shape和data type与原图像相同
    cv.add(src1, src2, add_result);
    cv.imshow("add_result", add_result);
    
    sub_result = np.zeros(src1.shape, src1.dtype);
    cv.subtract(src1, src2, sub_result);
    cv.imshow("sub_result", sub_result);
    
    mul_result = np.zeros(src1.shape, src1.dtype);
    cv.multiply(src1, src2, mul_result);
    cv.imshow("mul_result", mul_result);
    
    div_result = np.zeros(src1.shape, src1.dtype);
    cv.divide(src1, src2, div_result);
    cv.imshow("div_result", div_result);
    
    cv.waitKey(0)
    cv.destroyAllWindows()
    

    相关文章

      网友评论

          本文标题:005 图像像素的算术操作

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