「OpenCV3.4」图像多通道混合addWeighted、resize、copyTo、cvtColor、rectangle

文章目录

    • 运行结果
    • 编译文件
    • 源码解读
    • 多通道图像混合
    • 图像混合和同时显示多张图像
    • 图像混合
    • 两张图像叠加控件调整透明度

运行结果

「OpenCV3.4」图像多通道混合addWeighted、resize、copyTo、cvtColor、rectangle_第1张图片

编译文件

cmake_minimum_required(VERSION 2.8)
project(imageBasics)
set(CMAKE_BUILD_TYPE "Debug")
# 添加c++ 11标准支持
set(CMAKE_CXX_FLAGS "-std=c++11 -O2")

# 寻找OpenCV库
find_package(OpenCV REQUIRED)

add_executable(c_basis c_basis.cpp)
target_link_libraries(c_basis ${OpenCV_LIBS})

源码解读

#include 
#include 
#include 
#include 
#include 

int main(int argc, char **argv) {
  cv::Mat image; // 读取一张二维三通图像 新版本OpenCV中引入Mat类自动管理内存处理图像数据
  image = cv::imread("../ubuntu.png"); // cv::imread函数读取argv[1]指定路径下的图像
  if (image.data == nullptr) {
      std::cerr << "文件不存在" << std::endl;// 判断图像文件是否正确读取如果不能读取可能是文件不存在
      return 0; // 没有读取图片return 0终止函数
  }
  cv::imshow("image", image);
  cv::waitKey(0);

  std::cout << "image.size: " << image.size << std::endl; // image.size: 674 x 1200 高 宽
  std::cout << "image.rows: " << image.rows << std::endl; // image.rows: 674 高
  std::cout << "image.cols: " << image.cols << std::endl; // image.cols: 1200 宽
  std::cout << "image.rows/2: " << image.rows/2 << std::endl; // image.rows/2: 337 高/2  注意高度是有多少行的像素 
  std::cout << "image.cols/2: " << image.cols/2 << std::endl; // image.cols/2: 600 宽/2  注意宽度是有多少列的像素
  cv::Mat resize_image;
  cv::resize(image, resize_image, cv::Size(0,0),0.5,0.5,CV_INTER_LINEAR);
  /**
   * resize()函数
   * InputArray src, 输入原图像
   * OutputArray dst, 输出缩放后的图像
   * Size dsize, 输出图像的大小
   * 如果这个参数为0, 那么原图像缩放之后的大小就要通过下面的公式来计算
   * dsize = Size(round(fx*src.cols), round(fy*src.rows))
   * fx是fx:width方向的缩放比例,如果它是0,那么它就会按照(double)dsize给出的值来计算
   * fy是fy:height方向的缩放比例,如果它是0,那么它就会按照(double)dsize给出的值来计算
   * 如果这个参数不为0, 假如给出的是Size(width/2,height/2)代表将原图像在宽度和高度上缩小为原来的一半
   * fx=0.5 fy=0.5 和 Size(width/2,height/2)的缩放效果是一样的
   * 总结一下就是给出两种缩放比例参数的方法而已
   * 图像缩放之后像素要重新计算最后一个参数指定计算像素的方式有以下几种:
   * CV_INTER_NEAREST - 最邻近插值
   * CV_INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
   * CV_INTER_AREA - 基于局部像素的重采样
   * CV_INTER_CUBIC - 基于4x4像素邻域的3次插值法
   * CV_INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
   */
  cv::imshow("resize_image", resize_image);
  cv::waitKey(0);


  resize_image.copyTo(image(cv::Rect(0, 0, image.cols/2, image.rows/2)));
  resize_image.copyTo(image(cv::Rect(0, resize_image.rows, image.cols/2, image.rows/2)));
  resize_image.copyTo(image(cv::Rect(resize_image.cols, 0, image.cols/2, image.rows/2)));
  resize_image.copyTo(image(cv::Rect(resize_image.cols, resize_image.rows, image.cols/2, image.rows/2)));
  cv::imshow("image", image);
  cv::waitKey(0);
  /**
   * copyTo()函数的形式详解
   * image.copyTo(imageROI),作用是把image的内容复制粘贴到imageROI上
   * image.copyTo(imageROI,mask),作用是把mask和image重叠以后把mask中像素值为0(black)的点变为透明这样就会只显示image中的其它点了
   */

  cv::Mat mask;
  cv::resize(resize_image, mask, cv::Size(0,0),0.5,0.5,CV_INTER_LINEAR);
  cv::Mat mask_gray;
  cv::cvtColor(mask,mask_gray,CV_RGB2GRAY); // 加载掩模(必须是灰度图)
  mask.copyTo(resize_image(cv::Rect(0,0,mask.cols,mask.rows)),mask_gray); // 将掩膜拷贝到ROI
  cv::imshow("resize_image", resize_image);
  cv::waitKey(0);

  cv::rectangle(mask, cv::Rect(mask.cols-60, mask.rows-60, 60, 60), cv::Scalar(0, 0, 0), -1, 8);
  cv::Mat imageROI= resize_image(cv::Rect(0,0,mask.cols,mask.rows));
  cv::addWeighted(imageROI,0.5,mask,0.3,0.,imageROI);
  imshow("resize_image",resize_image);
  cv::waitKey(0);

  cv::destroyAllWindows();
  return 0;
}

多通道图像混合

#include 
#include 

using namespace cv;
using namespace std;

bool  MultiChannelBlending();

int main(){
	MultiChannelBlending();
	return 0;
}

//	描述:多通道混合的实现函数
bool  MultiChannelBlending(){
	Mat srcImage;
	Mat logoImage;
	vector<Mat> channels;
	Mat  imageBlueChannel;

	//	描述:多通道混合-蓝色分量部分
	logoImage = imread("../dota_logo.jpg",0);
    imshow("dota_logo",logoImage);
	srcImage = imread("../dota_jugg.jpg");
    imshow("dota_jugg",srcImage);

	//【2】把一个3通道图像转换成3个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的蓝色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageBlueChannel= channels.at(0);
	//【4】将原图的蓝色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageBlueChannel中
	addWeighted(imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
		logoImage,0.5,0,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow("srcImage");
	imshow("srcImage",srcImage);
	imwrite("../srcImage.png", srcImage);
	cvWaitKey(0);

	//	描述:多通道混合-绿色分量部分
	Mat  imageGreenChannel;

	//【1】重新读入图片
	logoImage= imread("../dota_logo.jpg",0);
    imshow("dota_logo",logoImage);
    srcImage= imread("../dota_jugg.jpg");
    imshow("dota_jugg",srcImage);

    //【2】将一个三通道图像转换成三个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的绿色通道的引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageGreenChannel= channels.at(1);
	//【4】将原图的绿色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageGreenChannel中
	addWeighted(imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
		logoImage,0.5,0.,imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个独立的单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow("srcImage");
	imshow("srcImage",srcImage);
    imwrite("../srcImage.png", srcImage);
    cvWaitKey(0);



	//	描述:多通道混合-红色分量部分
	Mat  imageRedChannel;

	//【1】重新读入图片
	logoImage= imread("../dota_logo.jpg",0);
    imshow("dota_logo",logoImage);
	srcImage= imread("../dota_jugg.jpg");
    imshow("dota_jugg",srcImage);

	//【2】将一个三通道图像转换成三个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的红色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageRedChannel= channels.at(2);
	//【4】将原图的红色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageRedChannel中
	addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
		logoImage,0.5,0.,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个独立的单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow("srcImage");
	imshow("srcImage",srcImage);
    imwrite("../srcImage.png", srcImage);
    waitKey(0);
    return true;
}


图像混合和同时显示多张图像

「OpenCV3.4」图像多通道混合addWeighted、resize、copyTo、cvtColor、rectangle_第2张图片

「OpenCV3.4」图像多通道混合addWeighted、resize、copyTo、cvtColor、rectangle_第3张图片
「OpenCV3.4」图像多通道混合addWeighted、resize、copyTo、cvtColor、rectangle_第4张图片

#include 
#include 
#include 
#include 
#include 

int main(int argc, char **argv) {
  cv::Mat image; // 读取一张二维三通图像 新版本OpenCV中引入Mat类自动管理内存处理图像数据
  image = cv::imread("../ubuntu.png"); // cv::imread函数读取argv[1]指定路径下的图像
  if (image.data == nullptr) {
      std::cerr << "文件不存在" << std::endl;// 判断图像文件是否正确读取如果不能读取可能是文件不存在
      return 0; // 没有读取图片return 0终止函数
  }
  cv::imshow("image", image);
  cv::waitKey(0);

  std::cout << "image.size: " << image.size << std::endl; // image.size: 674 x 1200 高 宽
  std::cout << "image.rows: " << image.rows << std::endl; // image.rows: 674 高
  std::cout << "image.cols: " << image.cols << std::endl; // image.cols: 1200 宽
  std::cout << "image.rows/2: " << image.rows/2 << std::endl; // image.rows/2: 337 高/2  注意高度是有多少行的像素 
  std::cout << "image.cols/2: " << image.cols/2 << std::endl; // image.cols/2: 600 宽/2  注意宽度是有多少列的像素
  cv::Mat resize_image;
  cv::resize(image, resize_image, cv::Size(0,0),0.5,0.5,CV_INTER_LINEAR);
  /**
   * resize()函数
   * InputArray src, 输入原图像
   * OutputArray dst, 输出缩放后的图像
   * Size dsize, 输出图像的大小
   * 如果这个参数为0, 那么原图像缩放之后的大小就要通过下面的公式来计算
   * dsize = Size(round(fx*src.cols), round(fy*src.rows))
   * fx是fx:width方向的缩放比例,如果它是0,那么它就会按照(double)dsize给出的值来计算
   * fy是fy:height方向的缩放比例,如果它是0,那么它就会按照(double)dsize给出的值来计算
   * 如果这个参数不为0, 假如给出的是Size(width/2,height/2)代表将原图像在宽度和高度上缩小为原来的一半
   * fx=0.5 fy=0.5 和 Size(width/2,height/2)的缩放效果是一样的
   * 总结一下就是给出两种缩放比例参数的方法而已
   * 图像缩放之后像素要重新计算最后一个参数指定计算像素的方式有以下几种:
   * CV_INTER_NEAREST - 最邻近插值
   * CV_INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
   * CV_INTER_AREA - 基于局部像素的重采样
   * CV_INTER_CUBIC - 基于4x4像素邻域的3次插值法
   * CV_INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
   */
  cv::imshow("resize_image", resize_image);
  cv::waitKey(0);


  resize_image.copyTo(image(cv::Rect(0, 0, image.cols/2, image.rows/2)));
  resize_image.copyTo(image(cv::Rect(0, resize_image.rows, image.cols/2, image.rows/2)));
  resize_image.copyTo(image(cv::Rect(resize_image.cols, 0, image.cols/2, image.rows/2)));
  resize_image.copyTo(image(cv::Rect(resize_image.cols, resize_image.rows, image.cols/2, image.rows/2)));
  cv::imshow("image", image);
  cv::waitKey(0);
  /**
   * copyTo()函数的形式详解
   * image.copyTo(imageROI),作用是把image的内容复制粘贴到imageROI上
   * image.copyTo(imageROI,mask),作用是把mask和image重叠以后把mask中像素值为0(black)的点变为透明这样就会只显示image中的其它点了
   */

  cv::Mat mask;
  cv::resize(resize_image, mask, cv::Size(0,0),0.5,0.5,CV_INTER_LINEAR);
  cv::Mat mask_gray;
  cv::cvtColor(mask,mask_gray,CV_RGB2GRAY); // 加载掩模(必须是灰度图)
  mask.copyTo(resize_image(cv::Rect(0,0,mask.cols,mask.rows)),mask_gray); // 将掩膜拷贝到ROI
  cv::imshow("resize_image", resize_image);
  cv::waitKey(0);

  cv::rectangle(mask, cv::Rect(mask.cols-60, mask.rows-60, 60, 60), cv::Scalar(0, 0, 0), -1, 8);
  cv::Mat imageROI= resize_image(cv::Rect(0,0,mask.cols,mask.rows));
  cv::addWeighted(imageROI,0.5,mask,0.3,0.,imageROI);
  imshow("resize_image",resize_image);
  cv::waitKey(0);

  cv::destroyAllWindows();
  return 0;
}

图像混合

「OpenCV3.4」图像多通道混合addWeighted、resize、copyTo、cvtColor、rectangle_第5张图片

#include 
#include 
using namespace cv;


int main( ){
    //-----------------------------------【二、初级图像混合】--------------------------------------
    //	描述:二、初级图像混合
    //--------------------------------------------------------------------------------------------------
    //载入图片
    Mat image= imread("../dota.jpg");
    //载入后先显示
    namedWindow("【2】原画图");
    imshow("【2】原画图",image);
    waitKey(0);


    Mat logo= imread("../dota_logo.jpg");
    namedWindow("【3】logo图");
    imshow("【3】logo图",logo);
    waitKey(0);

    // 定义一个Mat类型,用于存放,图像的ROI
    Mat imageROI_same_size_logo, imageROI_add;
    //方法一
    imageROI_same_size_logo= image(Rect(80,35,logo.cols,logo.rows));

    //方法二
    //imageROI= image(Range(350,350+logo.rows),Range(800,800+logo.cols));

    // 将logo加到原图上
    addWeighted(imageROI_same_size_logo,0.5,logo,0.3,0.,imageROI_same_size_logo);

    //显示结果
    namedWindow("【4】原画+logo图");
    imshow("【4】原画+logo图",image);

    //-----------------------------------【三、图像的输出】--------------------------------------
    //	描述:将一个Mat图像输出到图像文件
    //-----------------------------------------------------------------------------------------------
    //输出一张jpg图片到工程目录下
    imwrite("../由imwrite生成的图片.jpg",image);

    waitKey(0);

    return 0;
}

两张图像叠加控件调整透明度


//---------------------------------【头文件、命名空间包含部分】-------------------------------
//		描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include 
#include 
using namespace cv;

//-----------------------------------【宏定义部分】--------------------------------------------
//  描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME "【滑动条的创建&线性混合示例】"        //为窗口标题定义的宏


//-----------------------------------【全局变量声明部分】--------------------------------------
//		描述:全局变量声明
//-----------------------------------------------------------------------------------------------
const int g_nMaxAlphaValue = 100;//Alpha值的最大值
int g_nAlphaValueSlider;//滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;

//声明存储图像的变量
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;


//-----------------------------------【on_Trackbar( )函数】--------------------------------
//		描述:响应滑动条的回调函数
//------------------------------------------------------------------------------------------
void on_Trackbar( int, void* )
{
    //求出当前alpha值相对于最大值的比例
    g_dAlphaValue = (double) g_nAlphaValueSlider/g_nMaxAlphaValue ;
    //则beta值为1减去alpha值
    g_dBetaValue = ( 1.0 - g_dAlphaValue );

    //根据alpha和beta值进行线性混合
    addWeighted( g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);

    //显示效果图
    imshow( WINDOW_NAME, g_dstImage );
}


//--------------------------------------【main( )函数】-----------------------------------------
//		描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{


    //加载图像 (两图像的尺寸需相同)
    g_srcImage1 = imread("../11.jpg");
    g_srcImage2 = imread("../22.jpg");

    //设置滑动条初值为70
    g_nAlphaValueSlider = 70;

    //创建窗体
    namedWindow(WINDOW_NAME, 1);

    //在创建的窗体中创建一个滑动条控件
    char TrackbarName[50];
    sprintf( TrackbarName, "透明值 %d", g_nMaxAlphaValue );

    createTrackbar( TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar );

    //结果在回调函数中显示
    on_Trackbar( g_nAlphaValueSlider, 0 );

    //按任意键退出
    waitKey(0);

    return 0;
}

你可能感兴趣的:(从零开始学习SLAM,OpenCV3.4)