美文网首页
ROI区域的图像混合

ROI区域的图像混合

作者: 此间不留白 | 来源:发表于2020-10-11 20:23 被阅读0次

有两幅图像src1src2,通过依据权重相加的方式实现ROI区域的混合,通过cv::addWeighted()函数可以轻松地实现这一功能,对cv::addWeighted()的参数,作如下说明:

void addWeighted(
    cv::inputArray src1, //输入的第一幅图像数组
    double alpha,  //第一幅图像的权重参数,可以调整第一幅图像的透明度
    cv::inputArray src2, //输入的第二幅图像
    double beta,  //第二幅图像的权重参数
    double gamma, //加权总和的偏移量
    cv::outputArray dst, //输出的图像
    int dytpe =-1  //输入图像的类型
)

利用addWeighted()函数实习ROI区域混合的完整代码如下:

#include<opencv2/core.hpp>
#include<highgui.hpp>
#include<string>
using namespace cv;
int main(int argc, char* argv[])
{
    String src1Path = "G:\\visual_project\\cv_charpt5Exm\\charpt6Exm\\src1.jpg";
    String src2Path = "G:\\visual_project\\cv_charpt5Exm\\charpt6Exm\\src2.jpg";
    Mat src1 = imread(src1Path,1);
    Mat src2 = imread(src2Path, 1);
    if ( !src1.empty() && !src2.empty())
    {
                //src1 图像ROI区域的起始点坐标(x,y)
        int x = 0; 
        int y = 0;
              //src1 图像的ROI区域的宽和高
        int w = 220;
        int h = 220;
                // alpha 越大,src1的ROI区域的亮度越高
        double alpha = 0.3;
        double beta = 0.7;
                // 利用Rect 获取src1的ROI区域
        Mat roi1(src1,Rect(x, y, w, h));
               //利用Rect 获取src2的ROI区域,与src1的ROI区域加权处理
        Mat roi2(src2, Rect(0, 0, w, h));
        addWeighted(roi1, alpha, roi2, beta, 0.0,roi2);
        namedWindow("Alpha Blend", 1);
        imshow("Alpha blend", src2);
        //imshow("roi", roi1);
        waitKey(0);
        


    }
    return 0;
}



实现效果如下所示:


注意: 利用Rect处理图像矩阵问题时,最不容忽视的问题是数组越界的问题,所以要注意边界检查,本次实现中,应该使得roi1的坐标(x,y)和宽高(w1,h1)与roi2的宽高(w2,h2)应该满足((x+w1)<=w2 && (y+h1) <=h2),加入边界检查和完整输入输出的代码,参考github代码如下所示:

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

using namespace cv;
using namespace std;

void help(const char** argv) {
    cout << "\n\n"
        << "This program alpha blends the first image onto the other \n"
        << "alpha is the blending of the first image and beta onto the second\n"
        << "Call:\n"
        << argv[0] << " <path/blend_this_img> <path/onto_this_img> <where_to_blend_x> <where_to_blend_y> <alpha> <beta>\n\n"
        << "Example:\n"
        << " ./example_05-01 ../faceTemplate.jpg ../faces.png 230 155 0.8 0.2\n"
        << endl;
}



int main(int argc, const char** argv)
{
    help(argv);
    if (argc != 7) {
        cout << "ERROR: Wrong # of parameters (7), you had " << argc << "\n" << endl;
        return -1;
    }


    // Using the first two arguments, open up the image to be copied onto
    // (src1), and the image that will be copied from (src2).
    //
    cv::Mat src1 = cv::imread(argv[1], 1);
    cv::Mat src2 = cv::imread(argv[2], 1);

    int from_w = src1.size().width;
    int from_h = src1.size().height;
    int to_w = src2.size().width;
    int to_h = src2.size().height;


    if (argc == 7 && !src1.empty() && !src2.empty()) {

        // Four more arguments tell where in src1 to paste the chunk taken from
        // src2. Note that the width and height also specify what portion of
        // src2 to actually use.
        //
        int x = atoi(argv[3]);
        int y = atoi(argv[4]);

        // Make sure we don't exceed bounds:
        if ((x < 0) || (y < 0) || (x > to_w - 1) || (y > to_h - 1) || (x + from_w > to_w - 1) || (y + from_h > to_h)) {
            cout << "\nError, at (x,y) (" << x << ", " << y << "), your input image [w,h] [" << from_w << ", "
                << from_h << "] doesn't fit within the blend to image [w,h] [" << to_w << ", " << to_h << "]\n" << endl;
            return -1;
        }

        // Two more arguments set the blending coefficients.
        //
        double alpha = (double)atof(argv[5]);
        double beta = (double)atof(argv[6]);

        cv::Mat roi1(src1, cv::Rect(0, 0, from_w - 1, from_h - 1)); //Just take the whole thing
        cv::Mat roi2(src2, cv::Rect(x, y, from_w - 1, from_h - 1));

        // Blend together the image src2 onto the image src1
        // at the specified location.
        //
        cv::addWeighted(roi1, alpha, roi2, beta, 0.0, roi2);

        // Create a window to shoow the result and show it.
        //
        cv::namedWindow("Alpha Blend", 1);
        cv::imshow("Alpha Blend", src2);

        // Leave the window up and runnnig until the user hits a key
        //
        cv::waitKey(0);

    }

    return 0;

}

相关文章

网友评论

      本文标题:ROI区域的图像混合

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