图像处理——(源)addWeighted函数编程实现

本文深入探讨了OpenCV中addWeighted函数的原理及应用,作者不仅详细解析了该函数的工作机制,还提供了两种自定义实现的方法,通过实例演示了如何使用这些函数进行图像叠加,对比了不同实现方式的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

找了很久addWeighted函数的实现,硬是没找到,气的自己码一码。效果还不错。

源理是线性混合操作,g(x)=(1-a)f1(x)+af2(x),0<=a<=1;产生时间上的画面重叠。

像网上一样先来函数解析(找到的都是这个,讲一下函数怎么用,再调用一下函数看看效果,看得吐血)

addWeighted原函数:
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);

第一个参数:要叠加的第一个图像Mat

第二个参数:标识第一个参数叠加的权重

第三个参数:表示第二个叠加的图像,他需要和第一个数组拥有同样的尺寸和通道数

第四个参数:表示第二个叠加图像的权重

第五个参数:输出参数,需要和前两个图像拥有同样的通道数和尺寸

第六个参数:一个加到权重总和上的标量值(填0就好)

第七个参数:输出阵列的深度有默认值-1, 当两张叠加图片深度相同时,参数为-1

对应表达式为:dst = src1[i] * alpha + src2[i] * beta + gamma;//两张图片每个通道对应数值之和。

重点!!!!!!!!!!!!!!!!!!!

自己实现这个函数,三个图都是512*512*3

 1 #include <opencv2/opencv.hpp>
 2 #include <opencv2/core/core.hpp>
 3 #include<iostream>
 4 #include<stdlib.h>
 5 using namespace cv;
 6 using namespace std;
 7 //原int main()
 8 bool add()
 9 {    
10     Mat srcImage=imread("E://wpp.jpg");
11     if(!srcImage.data){
12         printf("error");
13         return false;
14     }
15     Mat logoImage=imread("E://opencv.jpg");    
16     if(!logoImage.data){
17         printf("error");
18         return false;
19     }
20     Mat ImageROI=srcImage(Rect(200,250,logoImage.cols,logoImage.rows));
21     Mat mask=imread("E://opencv.jpg",0);
22     logoImage.copyTo(ImageROI,mask);    
23     namedWindow("add");
24     imshow("add",srcImage);
25     waitKey(0);
26     return true;
27     
28 }
29 //原int main()
30 bool addw()
31 {
32     double alp=0.5;
33     double bet=0.5;
34     Mat src2,src3,dst;
35     src2=imread("E://wpp3.jpg");
36     src3=imread("E://rice.jpg");
37     resize(src2,src2,Size(500,500));
38     resize(src3,src3,Size(500,500));
39     addWeighted(src2,alp,src3,bet,0.0,dst);
40     namedWindow("addw");
41     imshow("addw",dst);
42     waitKey(0);
43     return true;
44 }
45 //方法一
46 void addweighted_my1(Mat & src1,double alpha,Mat &src2,double beta,double gama,Mat &src3,int dtype=-1)
47 {
48     int row=src1.rows;   //行数
49     int col=src1.cols*src1.channels();//列数*通道数=每一行元素个数
50     //行循环列循环
51     for(int i=0;i<row;i++){
52         uchar* data1=src1.ptr<uchar>(i);//获取第i行首地址
53         uchar* data2=src2.ptr<uchar>(i);
54         uchar* data3=src3.ptr<uchar>(i);
55         for(int j=0;j<col;j++){
56             data3[j]=data1[j]*0.4+data2[j]*0.6+gama;//g(x)=(1-a)f1(x)+af2(x)+gama,两个像素的加权和,产生时间上的画面叠加
57         }
58     }
59 }
60 //方法二
61 void addweighted_my2(Mat & src1,double alpha,Mat &src2,double beta,double gama,Mat &src3,int dtype=-1)
62 {
63     int row=src1.rows;   //行数
64     int col=src1.cols;   //列数
65     //行循环列循环
66     for(int i=0;i<row;i++){        
67         for(int j=0;j<col;j++){
68             src3.at<Vec3b>(i,j)[0]=alpha*src1.at<Vec3b>(i,j)[0]+beta*src2.at<Vec3b>(i,j)[0]+gama;//蓝色通道
69             src3.at<Vec3b>(i,j)[1]=alpha*src1.at<Vec3b>(i,j)[1]+beta*src2.at<Vec3b>(i,j)[1]+gama;//绿色通道
70             src3.at<Vec3b>(i,j)[2]=alpha*src1.at<Vec3b>(i,j)[2]+beta*src2.at<Vec3b>(i,j)[2]+gama;//红色通道
71         }
72     }
73 }
74 
75 
76 int main()
77 {
78     double alpha=0.4,beta=0.6;
79     double gama0=0;
80     double gama1=100;
81     double gama2=1000;
82     Mat src1=imread("E://lena.jpg");
83     Mat src2=imread("E://opencv.jpg");
84     Mat src3=imread("E://heibai.jpg");
85     imshow("lena",src1);
86     imshow("opencv",src2);
87     imshow("heibai",src3);
88     //addWeighted(src1,alpha,src2,beta,gama0,src3);
89     //addweighted_my1(src1,alpha,src2,beta,gama1,src3);
90     addweighted_my2(src1,alpha,src2,beta,gama2,src3);    
91     imshow("addweighted",src3);
92     waitKey(0);
93     return 0;
94     
95 }

运行结果

opencv自带的addWeighted效果:

addWeighted_my1自己写的函数的效果

addWeighted_my2自己写的函数的效果

 

 

追求本源,源理才是真正的原理!

完!!!!!!!!!

 

转载于:https://www.cnblogs.com/fpzs/p/11135160.html

### 手动实现图像处理编程代码示例 #### 使用Python和NumPy手动实现灰度转换 为了理解基本的图像处理操作,下面展示了如何使用Python和NumPy库来手动将彩色图像转换为灰度图像。 ```python import numpy as np from PIL import Image def rgb_to_grayscale(image_path): # 加载图片 img = Image.open(image_path).convert('RGB') # 将PIL.Image对象转为numpy数组 image_array = np.array(img, dtype=np.float32) # 获取尺寸 height, width, _ = image_array.shape # 创建一个新的空白灰度图像矩阵 gray_image = np.zeros((height, width), dtype=np.uint8) # 遍历每一个像素点计算其亮度值 (R*0.299 + G*0.587 + B*0.114),这是标准的色彩到灰度转化公式 for i in range(height): for j in range(width): r, g, b = image_array[i][j][:3] gray_value = int(r * 0.299 + g * 0.587 + b * 0.114) gray_image[i][j] = gray_value return Image.fromarray(gray_image) # 测试函数 rgb_to_grayscale('example.jpg').show() ``` 这段代码实现了从彩色图像到灰度图像的手动转换过程[^1]。此过程中并没有依赖任何高级别的计算机视觉库(如OpenCV),而是利用了基础的数据科学工具包——NumPy来进行数值运算,并借助Pillow库完成图像输入/输出功能。 #### 边缘检测算法实现 边缘检测是另一个重要的图像处理任务,在这里给出一种简单的Sobel算子方法: ```python import cv2 import matplotlib.pyplot as plt def sobel_edge_detection(image_path): # 加载并转化为灰度模式 img_gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 定义sobel卷积核 sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) sobel_y = np.array([[1, 2, 1], [0, 0, 0], [-1,-2,-1]]) # 应用滤波器 grad_x = cv2.filter2D(src=img_gray, ddepth=-1, kernel=sobel_x) grad_y = cv2.filter2D(src=img_gray, ddepth=-1, kernel=sobel_y) abs_grad_x = cv2.convertScaleAbs(grad_x) abs_grad_y = cv2.convertScaleAbs(grad_y) grad = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0) fig, ax = plt.subplots(1, 3, figsize=(15, 5)) ax[0].imshow(cv2.cvtColor(img_gray, cv2.COLOR_BGR2RGB)), ax[0].set_title("Original") ax[1].imshow(cv2.cvtColor(abs_grad_x, cv2.COLOR_BGR2RGB)), ax[1].set_title("|Gx|") ax[2].imshow(cv2.cvtColor(abs_grad_y, cv2.COLOR_BGR2RGB)), ax[2].set_title("|Gy|") plt.show() return grad # 调试该函数 edge_detected_img = sobel_edge_detection('example.png') plt.imshow(edge_detected_img, cmap='gray'), plt.title("Edge Detected"), plt.axis('off') plt.show() ``` 上述例子中,通过定义两个方向上的Sobel算子作为模板,分别对原始图像进行了水平和垂直方向的一阶微分近似,最后组合得到最终的结果图[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值