ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

图像的线性混合

2019-07-26 22:03:56  阅读:129  来源: 互联网

标签:dst linux 混合 图像 线性 alpha col row


目录


注:原创不易,转载请务必注明原作者和出处,感谢支持!

一 图像的线性混合

什么是图像的线性混合(linear blending)?

如下面的公式所示。所谓的图像线性混合是指对于输入的两张图像\(I_0\)和\(I_1\),取它们相同位置处的像素值进行线性相加,然后将结果赋值给目标图像相同位置处的像素。其中参数\(\alpha\)控制了两张图片在目标图像中的权重。
\[ g(x) = \alpha I_0(x) + (1-\alpha)I_1(x) \]

图像的线性混合有什么作用呢?在幻灯片翻页或者电影制作中,经常需要产生画面叠加的效果。在上式中,只要使得\(\alpha\)从1逐渐减小到0即可产生从图像\(I_0\)过渡到图像\(I_1\)时的叠加效果了。

OpenCV中提供了一个用于两张图像线性混合的API。API所依据的计算公式如下:
\[ dst(I) = saturate\_cast(src1(I) * alpha + src2(I) * beta + gamma) \]

void cv::addWeighted(
    InputArray src1,        // 输入图像1
    double alpha,           // 图像1的权重
    InputArray src2,        // 输入图像2
    double beta,            // 图像2的权重
    double gamma,           // gamma值
    OutputArray dst,        // 输出图像
    int dtype = -1          
);

注意:用于线性混合的两张图像必须是同等大小和同等类型的!


二 代码实现

如果不使用OpenCV提供的API,仅依靠OpenCV提供的像素级访问功能,则图像的线性混合可以实现如下。

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

using namespace cv;
using namespace std;

int main(int argc, char **argv)
{
    // load two images with the same size and type
    Mat windows = imread("D:\\IMG\\windows.jpg", IMREAD_COLOR);
    Mat linux = imread("D:\\IMG\\linux.jpg", IMREAD_COLOR);
    if (windows.empty() || linux.empty())
    {
        cout << "Error : could not load image." << endl;
        return -1;
    }
    imshow("input - windows", windows);
    imshow("input - linux", linux);

    // check if two images are with the same size and type
    if (windows.size() != linux.size() || windows.type() != linux.type())
    {
        cout << "Error : two input images do NOT match in size or type." << endl;
        return -1;
    }

    // parameters for linear blending
    double alpha = 0.5;
    double beta = 1 - alpha;
    double gamma = 0.0;

    Mat dst(windows.size(), windows.type());
    decltype(windows.rows) row, col;
    double output, b, g, r;
    int f1, f2, b1, b2, g1, g2, r1, r2;

    for (row = 0; row < windows.rows; ++row)
    {
        for (col = 0; col < windows.cols; ++col)
        {
            // single channel (gray image) or three channels (RGB image) only
            if (windows.channels() == 1)
            {
                f1 = windows.at<uchar>(row, col);
                f2 = linux.at<uchar>(row, col);
                output = f1 * alpha + f2 * beta + gamma;
                dst.at<uchar>(row, col) = saturate_cast<uchar>(output);
            }
            else if (windows.channels() == 3)
            {
                b1 = windows.at<Vec3b>(row, col)[0];
                b2 = linux.at<Vec3b>(row, col)[0];
                g1 = windows.at<Vec3b>(row, col)[1];
                g2 = linux.at<Vec3b>(row, col)[1];
                r1 = windows.at<Vec3b>(row, col)[2];
                r2 = linux.at<Vec3b>(row, col)[2];
                b = b1 * alpha + b2 * beta + gamma;
                g = g1 * alpha + g2 * beta + gamma;
                r = r1 * alpha + r2 * beta + gamma;
                
                dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b);
                dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g);
                dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r);
            }
        }
    }
    imshow("output (alpha = 0.5)", dst);

    waitKey(0);
    return 0;
}

如果使用addWeighted(),则可以简单地实现如下

addWeighted(windows, alpha, linux, beta, 0, dst);
imshow("output (alpha = 0.9)", dst);

三 实现效果

(1) 两张原图

(2) 手写代码实现,\(\alpha\)值分别为0.1、0.5、0.9

(3) 调用API实现,\(\alpha\)值分别为0.1、0.5、0.9

可以看到,手写代码实现所呈现的效果和调用APIaddWeighted()的效果并没有明显的差异。但很可能的是自己手写的与API相比,性能会更差一点。

标签:dst,linux,混合,图像,线性,alpha,col,row
来源: https://www.cnblogs.com/laizhenghong2012/p/11253100.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有