OpenCV之图像处理(六) 图像混合

图像混合有 ·加·减·乘·除·比重 等方式

VS代码

    #include "../common/common.hpp"

    void main1_6(int argc, char ** argv)
    {
        Mat src1 = imread(getCVImagesPath("images/LinuxLogo.jpg"), IMREAD_COLOR);
        Mat src2 = imread(getCVImagesPath("images/WindowsLogo.jpg"), IMREAD_COLOR);
        if (!(src1.rows==src2.rows && src1.cols==src2.cols && src1.type()== src2.type()))
        {
            cout << "两张图像大小或者类型不一致" << endl;
            getchar();
            return;
        }
        Mat dst1, dst2, dst3, dst4, dst5, dst6;
        double alpha = 0.5;
        //理论-线性混合操作: g(x) = (1-α)*f0(x) + α*f1(x)  其中α的取值范围为0~1之间,f0(x)表示一张图像x位置像素点的颜色数据,f1(x)表示另一张
        //输出的混合图像计算公式 : dst(I) = saturate_cast(src1(I)*alpha + src2(I)*beta + gamma)  这里计算的是两张图像对应位置像素点的颜色数据
        //参数:输入图像1、图像1的比重、输入图像2、图像2的比重、gamma值(如果混合的图像较暗,可以使其变量)、输出混合图像。  两张图像的大小和类型必须一致才可以
        addWeighted(src1, alpha, src2, 1 - alpha, 0.0, dst1);//由计算公式可以看出dst是由src1、src2个一半合成的
        add(src1, src2, dst2, Mat());// dst(I) = saturate_cast(src1(I) + src2(I))  将对应位置像素点颜色数据直接相加
        add(src1, Scalar(0, 0, 55), dst3);// dst(I) = saturate_cast(src1(I) + Scalar(I))  将对应位置像素点颜色数据直接加上固定颜色像素值,这里src是三通道的RGB,所以Scalar也是3
        subtract(src1, src2, dst4, Mat());// dst(I) = saturate_cast(src1(I) - src2(I))  将对应位置像素点颜色数据直接相减,同add一样,也可以减Scalar
        multiply(src1, src2, dst5, 1.0);// dst(I) = saturate_cast(src1(I) * src2(I) * scale)  将对应位置像素点颜色数据相乘再乘scale,同add一样,也可以乘Scalar
        divide(src2, src1, dst6, 2.0);// dst(I) = saturate_cast((src1(I)/src2(I)) * scale)  将对应位置像素点颜色数据相除再乘scale,同add一样,也可以除Scalar
        imshow("src1", src1);
        imshow("src2", src2);
        imshow("addWeighted", dst1);
        imshow("add_src2", dst2);
        imshow("add_scalar", dst3);
        imshow("subtract", dst4);
        imshow("multiply", dst5);
        imshow("divide", dst6);

        waitKey(0);
    }

效果图

这里写图片描述

Android代码

@BindView(R.id.iv_opencv1_6_input) ImageView mLinuxLogIv;
@BindView(R.id.iv_opencv1_6_output1) ImageView mWinLogIv;
@BindView(R.id.iv_opencv1_6_output2) ImageView mAddWeightedIv;
@BindView(R.id.iv_opencv1_6_output3) ImageView mAddSrcIv;
@BindView(R.id.iv_opencv1_6_output4) ImageView mAddScalarIv;
@BindView(R.id.iv_opencv1_6_output5) ImageView mSubtractIv;
@BindView(R.id.iv_opencv1_6_output6) ImageView mMultiplyIv;
@BindView(R.id.iv_opencv1_6_output7) ImageView mDivideIv;
private Bitmap mLinuxLogBmp;
private Bitmap mWinLogBmp;
private Bitmap mAddWeightedBmp;
private Bitmap mAddSrcBmp;
private Bitmap mAddScalarBmp;
private Bitmap mSubtractBmp;
private Bitmap mMultiplyBmp;
private Bitmap mDivideBmp;
private Mat mLinuxLogMat = new Mat();
private Mat mWinLogMat = new Mat();
private Mat mAddWeightedMat = new Mat();
private Mat mAddSrcMat = new Mat();
private Mat mAddScalarMat = new Mat();
private Mat mSubtractMat = new Mat();
private Mat mMultiplyMat = new Mat();
private Mat mDivideMat = new Mat();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cv1_6);
    mUnbinder = ButterKnife.bind(this);

    //linux log
    mLinuxLogBmp = CV310Utils.getBitmapFromAssets(this, "opencv/LinuxLogo.jpg");
    mLinuxLogIv.setImageBitmap(mLinuxLogBmp);
    Utils.bitmapToMat(mLinuxLogBmp, mLinuxLogMat);

    //win log
    mWinLogBmp = CV310Utils.getBitmapFromAssets(this, "opencv/WindowsLogo.jpg");
    mWinLogIv.setImageBitmap(mWinLogBmp);
    Utils.bitmapToMat(mWinLogBmp, mWinLogMat);
    initBitmaps(mWinLogBmp);

    //addWeighted
    double alpha = 0.5;
    //理论-线性混合操作: g(x) = (1-α)*f0(x) + α*f1(x)  其中α的取值范围为0~1之间,f0(x)表示一张图像x位置像素点的颜色数据,f1(x)表示另一张
    //输出的混合图像计算公式 : dst(I) = saturate_cast(src1(I)*alpha + src2(I)*beta + gamma)  这里计算的是两张图像对应位置像素点的颜色数据
    //参数:输入图像1、图像1的比重、输入图像2、图像2的比重、gamma值(如果混合的图像较暗,可以使其变量)、输出混合图像。  两张图像的大小和类型必须一致才可以
    Core.addWeighted(mLinuxLogMat, alpha, mWinLogMat, 1-alpha, 0.0, mAddWeightedMat);//由计算公式可以看出dst是由src1、src2个一半合成的
    Utils.matToBitmap(mAddWeightedMat, mAddWeightedBmp);
    mAddWeightedIv.setImageBitmap(mAddWeightedBmp);

    //add src
    Core.add(mLinuxLogMat, mWinLogMat, mAddSrcMat);// dst(I) = saturate_cast(src1(I) + src2(I))  将对应位置像素点颜色数据直接相加
    Utils.matToBitmap(mAddSrcMat, mAddSrcBmp);
    mAddSrcIv.setImageBitmap(mAddSrcBmp);

    //add scalar
    Core.add(mLinuxLogMat, new Scalar(55, 0, 0, 0), mAddScalarMat);// dst(I) = saturate_cast(src1(I) + Scalar(I))  将对应位置像素点颜色数据直接加上固定像素值,这里src是四通道的RGBA,所以Scalar也是4
    Utils.matToBitmap(mAddScalarMat, mAddScalarBmp);
    mAddScalarIv.setImageBitmap(mAddScalarBmp);

    //subtract
    Core.subtract(mLinuxLogMat, mWinLogMat, mSubtractMat);// dst(I) = saturate_cast(src1(I) - src2(I))  将对应位置像素点颜色数据直接相减,同add一样,也可以减Scalar
    Utils.matToBitmap(mSubtractMat, mSubtractBmp);
    mSubtractIv.setImageBitmap(mSubtractBmp);

    //multiply
    Core.multiply(mLinuxLogMat, mWinLogMat, mMultiplyMat, 1.0);// dst(I) = saturate_cast(src1(I) * src2(I) * scale)  将对应位置像素点颜色数据相乘再乘scale,同add一样,也可以乘Scalar
    Utils.matToBitmap(mMultiplyMat, mMultiplyBmp);
    mMultiplyIv.setImageBitmap(mMultiplyBmp);

    //divide
    Core.divide(mWinLogMat, mLinuxLogMat, mDivideMat, 2.0);// dst(I) = saturate_cast((src1(I)/src2(I)) * scale)  将对应位置像素点颜色数据相除再乘scale,同add一样,也可以除Scalar
    Utils.matToBitmap(mDivideMat, mDivideBmp);
    mDivideIv.setImageBitmap(mDivideBmp);
}

/*初始化bitmap*/
private void initBitmaps(Bitmap bmp){
    mAddWeightedBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
    mAddSrcBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
    mAddScalarBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
    mSubtractBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
    mMultiplyBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
    mDivideBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
}

效果图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/80875691