【图像处理OpenCV(C++版)】——3.3 几何变换之极坐标变换

news2025/1/21 12:05:31

前言

😊😊😊欢迎来到本博客😊😊😊

🌟🌟🌟 本专栏主要结合OpenCV和C++来实现一些基本的图像处理算法并详细解释各参数含义,适用于平时学习、工作快速查询等,随时更新。

😊😊😊 具体食用方式:可以点击本专栏【OpenCV快速查找(更新中)】–>搜索你要查询的算子名称或相关知识点,或者通过这篇博客👉通俗易懂OpenCV(C++版)详细教程——OpenCV函数快速查找(不断更新中)]查阅你想知道的知识,即可食用。

🎁🎁🎁支持:如果觉得博主的文章还不错或者您用得到的话,可以悄悄关注一下博主哈,如果三连收藏支持就更好啦!这就是给予我最大的支持!😙😙😙


文章目录

    • 学习目标
    • 一、极坐标变换原理
      • 1.1、笛卡儿坐标转换为极坐标
      • 1.2、极坐标转换为笛卡儿坐标
      • 1.3、利用极坐标变换对图像进行变换
    • 二、常见极坐标变换函数
      • 2.1、线性极坐标函数linearPolar()
      • 2.2、对数极坐标函数logPolar()
    • 三、 总结

学习目标

  • 熟悉极坐标变换原理
  • 了解常见极坐标变换函数
  • C++实现极坐标变换案例

一、极坐标变换原理

  之前介绍的几种几何变换,如投影变换和仿射变换都是笛卡儿坐标系之间的变换,下面介绍笛卡
儿平面坐标和极坐标之间的空间变换关系,从而完成图像的极坐标变换
  

1.1、笛卡儿坐标转换为极坐标

  在笛卡尔坐标系xoy平面上的一点(x,y),以(x',y’)为中心,通过以下公式将笛卡儿坐标转换为极坐标:

  从上述公式可以看出,以变换中心为圆心的同一个圆上的点,在极坐标系θ & r中显示为一条直线。θ的取值范围用弧度表示[0,2π]用角度表示[0,360],反正切函数arctan2返回的角度和笛卡儿坐标点所在的象限有关系

象限反正切角度范围
(y-y',x-x')在第一象限[0,90]
(y-y',x-x')在第二象限[90,180]
(y-y',x-x')在第三象限[-180,-90]
(y-y',x-x')在第四象限[-90,0]

  为了使用方便,将第三、四象限情况,即(y-y')≤0时返回的正切角度加上一个周期360 ° ,所以经过极坐标变换后的角度范围为[0,360]

  OpenCV提供了函数:

void cartToPolar(InputArray x,
InputArray y,
OutputArray magnitude,
OutputArray angle,
bool angleInDegrees = false 
)	

  将原点移动到变换中心后的笛卡儿坐标向极坐标的变换,其参数解释如下表所示,返回值magnitudeangle是与参数x和y具有相同尺寸和数据类型的ndarray

参数注释
x输入,单精度或双精度浮点型数组。float_32float_64
y与x一致
magnitude输出,极径,单精度或双精度浮点型数组。
angle输出,极角,可为角度或弧度。
angleInDegrees输入,为True时,angle为角度;为False时,angle为弧度

  举例:计算(0,0)、(1,0)、(2,0)、(0,1)、(1,1)、(2,1)、(0,2)、(1,2)、(2,2)这9个点以(1,1)为中心进行的极坐标变换。首先将坐标原点移动到(1,1)处,按照平移仿射矩阵计算出这9个点平移后的新坐标值,然后利用函数cartToPolar进行极坐标变换。代码如下:

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

using namespace std;
using namespace cv;
int main() {
	Mat x = (Mat_<float>(3, 3) << 0, 1, 2, 0, 1, 2, 0, 1, 2);
	Mat y = (Mat_<float>(3, 3) << 0, 0,0, 1, 1, 1, 2, 2,2);
	Mat r, theta;
	Mat r1, theta1;
	cartToPolar(x,y,r, theta, true);//角度
	cartToPolar(x, y, r1,theta1, false);//弧度

	cout << "极径:"<< r<< endl;
	cout << "对应角度信息:" << theta << endl;
	cout << "==================================="  << endl;
	cout << "极径:" << r1 << endl;
	cout << "对应弧度信息:" << theta1 << endl;

	return 0;
}

  

1.2、极坐标转换为笛卡儿坐标

  极坐标变换也是可逆的,在已知极坐标(θ,r)和笛卡儿坐标的条件下,计算哪个笛卡儿坐标(x,y)以 为中心的极坐标变换是(θ,r),可通过以下公式计算:

  OpenCV提供了函数:

void polarToCart	(InputArray magnitude,
InputArray angle,
OutputArray x,
OutputArray y,
bool angleInDegrees = false 
)	

  将极坐标转换为笛卡儿坐标,其参数解释与函数cartToPolar类似。注意:返回的是以原点(0,0)为中心的笛卡儿坐标,即已知(θ,r)(x',y') ,计算出的是(x-x',y-y')

参数注释
magnitude输入,极径,单精度或双精度浮点型数组。
angle输入,极角,可为角度或弧度。
x输出,单精度或双精度浮点型数组。float_32float_64
y与x一致
angleInDegrees输入,为True时,angle为角度;为False时,angle为弧度

  举例:已知极坐标系θ & r中的(30,10)、(31,10)、(30,11)、(31,11),其中θ是以角度表示的,问笛卡儿坐标系xoy中的哪四个坐标是以(-15,15)为中心经过极坐标变换后得到这四个坐标。代码如下:

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

using namespace std;
using namespace cv;
int main() {

	//极坐标转笛卡尔
	Mat angle = (Mat_<float>(2, 2) <<30,31,30,31);
	Mat r = (Mat_<float>(2, 2) <<10,10,11,11);
	Mat x, y;

	polarToCart(r,angle,x,y,true);

	x += -15;
	y += 15;

	for (int i = 0; i < x.rows; i++)
	{
		for (int j = 0; j < x.cols; j++)
		{
			cout << "笛卡尔坐标为:(" <<x.at<float>(i,j)<<","<< y.at<float>(i, j)<<")"<< endl;
		}
	}

	return 0;

}

  为什么要x+=-15,y+=15呢?
  得到的(x,y)是以(0,0)为变换中心的,而这里的变换中心为(-15,15),所以只要进行x+=-15,y+=15操作。

  

1.3、利用极坐标变换对图像进行变换

  假设输入图像矩阵为I(x',y')代表极坐标空间变换的中心,输出图像矩阵为O,比较简单的方法就是利用极坐标和笛卡儿坐标的一一对应关系得到O的每一个像素值,即:

  这里的θ和r都是以1为步长进行离散化的,由于变换步长较大,输出图像矩阵O可能会损失原图的很多信息。

  但是,可以进行优化,假设要将与(x',y')距离范围为[rmin ,rmax ]、角度范围在[θmin ,θmax]内的点进行极坐标向笛卡儿坐标的变换,当然这个范围内的点也是无穷多的,仍需要离散化;假设r的变换步长为rstep >0;sstep ≤1,θ的变换步长为θstep ,θstep 一般取360/180*NN≥2。那么,输出的图像矩阵的宽和高为:

  图像矩阵O的第i行第j列的值通过以下公式进行计算:

  在C++中可以通过先确定输出图像的宽、高,以及rθ的最小值和变换步长,从而估算出r和θ的最大值。在实现极坐标变换之前,先介绍一下OpenCV中的几个函数

  (1) 该函数实现矩阵的平铺

repeat(const Mat&src,int ny,int nx)
参数注释
src输入矩阵。
ny将src在垂直方向上重复ny次。
nx将src在水平方向上重复nx次。

  (2) 实现图像的极坐标变换

Mat polar (Mat I,Point2f center ,Size size, float minr = 0float mintheta=0float thetaStep = 0float rStep =0)
参数注释
I输入图像
center极坐标变换中心
minr与变换中心的最小距离
mintheta与变换中心的最小角度
thetaStep角度的变换步长
rStep距离的变换步长

  (3) 实现矩阵的水平镜像、垂直镜像及逆时针旋转180 °

void flip(InputArray src, OutputArray dst, int flipCode)
参数注释
src输入图像矩阵
dst输出图像矩阵,尺寸与数据类型与src一致
flipCode>0:src绕y轴镜像处理; =0src绕x轴镜像处理 ;<0:逆时针旋转180°(先绕x镜像,再绕y镜像)
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;
int main() {
	//flip(src,dst,flipcode)函数

	Mat src = imread("D:/VSCodeFile/OpenCV_CSDN/image/logo.jpeg", IMREAD_COLOR);
	Mat dst,dst1,dst2;
	flip(src,dst,1);//绕y轴镜像处理
	flip(src, dst1, 0);//绕x轴镜像处理
	flip(src, dst2, -1);//逆时针旋转180
	imshow("src原图", src);
	namedWindow("src原图", WINDOW_AUTOSIZE);

	putTextHusky(dst, "绕y轴镜像处理", Point(30, 30), Scalar(0, 0, 255), 20, "Arial");
	imshow("绕y轴镜像处理", dst);
	namedWindow("绕y轴镜像处理", WINDOW_AUTOSIZE);
	
	putTextHusky(dst1, "绕x轴镜像处理", Point(30, 30), Scalar(0, 0, 255), 20, "Arial");
	imshow("绕x轴镜像处理", dst1);
	namedWindow("绕x轴镜像处理", WINDOW_AUTOSIZE);
	
	putTextHusky(dst2, "逆时针旋转180 ", Point(30, 30), Scalar(0, 0, 255),20, "Arial");
	imshow("逆时针旋转180", dst2);
	namedWindow("逆时针旋转180", WINDOW_AUTOSIZE);
	
	waitKey(0);

	return 0;

}

极坐标变换对图像进行变换

  极坐标变换是比较耗时的运算,有的时候只需对距离变换中心一定范围内的点进行极坐标变换即可;当然,角度也与之类似,有的时候不需要是整个的0~360 ° 。比如图像中的圆环区域进行极坐标变换,这个圆环区域与中心点(x,y)的距离在某个范围内。

  分析:下面进行图像的极坐标变换,处理下列图像为例。下图所示的图像宽为942、高为910,其中有2层圆环,目的是将圆环按照“矩形”展示,通过极坐标变换正好可以实现该功能,圆环的中心大概位置为(466,453),将它作为极坐标变换中心。比如只对图像中"星座"符号圆环区域进行极坐标变换,这个圆环区域与中心点(466,453)的距离在 100~230 范围内,这个区域也是估算获得,那么可以令minr=100rStep=1,从而输出图像的高大约等于130(230-100),令mintheta=0thetastep=1/4、因为是整个圆环即需要角度范围是[0,360],则设置输出图像的宽大约等于360*4=1440。代码如下:

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

using namespace std;
using namespace cv;
int main() {
	Mat src = imread("D:/VSCodeFile/OpenCV_CSDN/image/img1.png", IMREAD_COLOR);
	if (!src.data)
	{
		return -1;
	}

	//图像极坐标变换
	float thetastep = 1.0 / 4;
	float minr = 100;
	Size size(int(360 / thetastep), 130);
	Mat dst = polar(src, Point2f(466, 453), size, minr);

	flip(dst, dst, 0); //绕x轴镜像处理

	imshow("src", src);
	imshow("dst", dst);

	waitKey(0);
	return 0;

}

注:我opencv3.4好像没有polar()函数,此问题待解决,先把代码呈上。

  

二、常见极坐标变换函数

2.1、线性极坐标函数linearPolar()

  线性极坐标函数linearPolar()如下:

void linearPolar(InputArray src,OutputArray dst,Point2f center,double maxRadius,int flags);
参数注释
src输入图像矩阵
dst输出图像矩阵,尺寸与数据类型与src一致
center极坐标变换中心
maxRadius极坐标变换得最大距离
flags插值算法,与函数resizewarpAffine得插值算法一致

  利用该函数的C++处理上面的那个图像,极坐标变换中心和上面代码中的中心是相同的,取最大距离为230,具体代码如下:

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

using namespace std;
using namespace cv;
int main() {
	//极坐标对图像进行转换linearPolar函数
	Mat src = imread("D:/VSCodeFile/OpenCV_CSDN/image/img1.png", IMREAD_COLOR);
	if (!src.data)
	{
		return -1;
	}

	//图像极坐标变换
	float maxr = 230;
	uchar flags = CV_INTER_LINEAR;

	//Mat dst = polar(src, Point2f(466, 453), size, minr);
	Mat dst;
	linearPolar(src, dst, Point2f(466, 453), maxr, flags);

	//显示
	imshow("src", src);
	imshow("dst", dst);

	waitKey(0);

	return 0;

}

注:上面polar()函数结果与次类似。

  函数linearPolar生成的极坐标,θ在垂直方向上,r在水平方向上,前面实现的极坐标变换r在垂直方向上,θ在水平方向上,所以旋转90 ° 得到的结果就会类似。

  仔细观察,里面的字好像也是在垂直方向上被压缩了,主要由于θ步长有点大造成的,那么该函数的rθ的变换步长是多少呢?假设src的尺寸为宽W、高H,因为输出图像的尺寸也为宽W、高H,所以角度θ的变换步长大约为360/Hr的变换步长大约为maxRadius/W,上图图像的高为453、宽为466,所以r的变换步长为230/466,θ的变换步长为360/453,比上面θ的变换步长thetastep=1/4还要大,因此会显得有些扁。

  该函数有两个缺点第一,极坐标变换的步长是不可控制的,导致得到的图可能不是很理想;第二,该函数只能对整个圆内区域,而无法对一个指定的圆环区域进行极坐标变换。除了线性极坐标变换,

  OpenCV还实现了另一种极坐标变换——对数极坐标变换,它们在本质上是相同的。

  

2.2、对数极坐标函数logPolar()

  对数极坐标函数logPolar()如下:

void logPolar(InputArray src,OutputArray dst,Point2f center,double M,int flags);
参数注释
src输入图像矩阵
dst输出图像矩阵,尺寸与数据类型与src一致
center极坐标变换中心
M系数,大一点效果更好
flagsWARP_FILL_OUTLIERS:笛卡儿坐标向对数极坐标变换;WARP_INVERSE_MAP:对数极坐标向笛卡儿坐标变换

  本质上,对数极坐标变换和线性极坐标变换是一样的,将笛卡儿坐标转换为对数极坐标的公式如下:

  反过来,将对数极坐标转换为笛卡儿坐标的公式如下:

  对比标准的线性极坐标变换公式,显然M值越小,得到的r方向上的压缩越大,在图像上的表现就是在r方向上的信息越来越少,所以设置M值大一点效果会好一些。还是以上图为例,代码如下:


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

using namespace std;
using namespace cv;
int main() {
	//极坐标对图像进行转换logPolar函数

	Mat src = imread("D:/VSCodeFile/OpenCV_CSDN/image/img1.png", IMREAD_COLOR);
	if (!src.data)
	{
	return -1;
	}

	//图像极坐标变换
	float maxr = 230;
	uchar flags = WARP_FILL_OUTLIERS;



	//Mat dst = polar(src, Point2f(466, 453), size, minr);
	Mat dst, dst1, dst2;
	//linearPolar(src, dst, Point2f(466, 453), maxr, flags);


	logPolar(src,dst, Point2f(466, 453),50,flags);
	logPolar(src, dst1, Point2f(466, 453),100, flags);
	logPolar(src, dst2, Point2f(466, 453), 150, flags);


	//显示
	imshow("src", src);
	imshow("dst-M:50", dst);
	imshow("dst-M:100", dst1);
	imshow("dst-M:150", dst2);

	waitKey(0);
	
	return 0;


}

三、 总结

  最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。OpenCV是学习图像处理理论知识比较好的一个途径,大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,有什么问题希望大家可以积极评论交流,我也会及时更新,来督促自己学习进度。希望大家觉得不错的可以点赞、关注、收藏。


🚶🚶🚶 今天的文章就到这里啦~
喜欢的话,点赞👍、收藏⭐️、关注💟哦 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB | 如何从热图中提取数据

这期做了个可能有用的小工具&#xff0c;一般论文中热图很少给出数据&#xff0c;于是就想写个小工具通过热图上的颜色估计出数据值来&#xff0c;目前写了个初版的工具分享给大家&#xff01; 工具函数 由于只是初版&#xff0c;要手动改的地方还是不少的&#xff0c;要设置…

PHP多商户AI智能在线客服系统源码 机器人自动回复 即时通讯聊天系统源码

一套智能在线客服系统源码 多商户网页客服系统源码 支持二十种国际语言 带机器人自动回复。 框架&#xff1a;Thinkphp5workerman&#xff0c; 环境&#xff1a;nginxphp7.3mysql5.6 支持H5公众号APP小程序 了解更多可私信我&#xff01; 系统功能&#xff1a; 1、支持国际…

编写程序时调用第三方程序时使用的是相对路径而不是绝对路径会造成什么严重后果(Windows Linux)

简介 在编写程序时&#xff0c;有很多人调用第三方程序使用的是相对路径&#xff0c;而不是绝对路径&#xff0c;如下&#xff1a; #!/bin/python3import osos.system("whoami") #调用whoami程序&#xff0c;查看当前用户名#!/bin/bashfind / -name "hellowor…

day10|239. 滑动窗口最大值、347.前 K 个高频元素

239. 滑动窗口最大值 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,3…

如何修改视频MD5的格式?这些方法值得你收藏

MD5实际上是计算机安全领域中广泛使用的一种散列函数&#xff0c;可以用来保护消息的完整性&#xff0c;简单来说就是类似于我们的指纹&#xff0c;可以说MD5是每个文件的“数字指纹”。比如&#xff1a;我们在平台上传一些热门视频&#xff0c;平台会自动识别视频的MD5值&…

嵌入式 LINUX 驱动开发 day01 第一个内核模块程序 多文件编译为一个程序, 内核模块参数, 内核模块依赖

1.第一个内核模块程序 ( 记得配置自己的交叉编译的工具,) 首先两个文件 vser.c Makefile (记得大写的M) vser.c #include <linux/init.h> //内核初始化头文件 #include <linux/module.h> //内核模块文件 #include <linux/kernel.h> //&…

Java基础算法每日5道详解(6)

112. Path Sum 路径总和 Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum. A leaf is a node with no children. Example 1: Input: ro…

html+css实现一个响应式管理平台架构模板

文本将会带你使用htmlcss实现一个响应式的管理平台架构模板&#xff0c;目前来说市面上的管理平台架构模板大同小异&#xff0c;文本的知识点都会符合场景所需。 目录 1、管理平台的架构内容 2、顶部的布局 3、下半部分布局 4、左侧菜单区域实现 5、右侧主体区域实现 …

前端重新部署如何通知用户刷新网页?

我把我掘金的文章同步一份给CSDN 1.目标场景 有时候上完线&#xff0c;用户还停留在老的页面&#xff0c;用户不知道网页重新部署了&#xff0c;跳转页面的时候有时候js连接hash变了导致报错跳不过去&#xff0c;并且用户体验不到新功能。 2.思考解决方案 如何去解决这个问…

顶象助力绿球金科打造App低碳出行场景

“低碳出行”、“碳中和”、“碳惠普”正在成为近几年的科技热词之一。 自2020年9月&#xff0c;中国向世界许下“力争2030年前实现碳达峰&#xff0c;2060年前实现碳中和”的承诺以来&#xff0c;一场围绕绿色节能、低碳减排的变革正在席卷各行各业。 “碳中和”已经成为时代…

如何让SCI期刊审稿人,理解你的文章? - 易智编译EaseEditing

首先需要对论文进行全文润色 对于发表论文来说&#xff0c;进行润色是必须的&#xff0c;正因为SCI论文翻译要求高难度大&#xff0c;无论笔译还是口译都一定要有过硬的基本功&#xff0c;知识面要足够宽广&#xff0c;专业综合能力要求高。 所以当一篇论文的整体结构不到位&…

凯恩帝机床联网

一、设备信息确认 1、确认型号 数控面板拍照确认&#xff1a; 此系统为&#xff1a;K1TCi 注&#xff1a;凡是系统中带i的&#xff0c;基本上都含网口。 2、确认通讯接口 网口常见位置&#xff0c;XS92&#xff08;丝印标号&#xff09;&#xff0c;可通过这个确认&#x…

PnetLab模拟器安装锐捷镜像

安装准备&#xff1a; 1.安装完成pnetlab&#xff0c;这里不过多叙述&#xff1b; 2.在锐捷的网站下载好模拟器镜像&#xff08;目前只支持Switch和Router&#xff09;&#xff0c;下载地址&#xff1a;https://www.ruijie.com.cn/fw/wd/88899/ 官网下载后的内容包括下面几个…

Linux umount报错:device is busy

执行nfs卸载命令umount /mnt&#xff0c;报错target is busy. 或device is busy可以按以下步骤检查&#xff1a;退出要卸载挂载的目录&#xff0c;再执行卸载挂载cd ../umount /mnt找出占用目录的端口&#xff0c;kill端口fuser -m /mnt/kill -9 端口umount /mnt停止nfs服务&am…

计算机基础——操作系统

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.操作系统 1.操作系统简介 2.操作系统的主要功能 &#xff08;1&#xff…

【Kotlin】字符串操作 ② ( 字符串替换函数 replace | 字符串比较操作符 == 和 === | 字符串遍历 forEach )

文章目录一、字符串替换函数 replace二、字符串比较操作符 和 三、字符串遍历 forEach一、字符串替换函数 replace 字符串替换函数 replace 函数原型如下 : /*** 返回一个新字符串&#xff0c;通过替换此字符序列中匹配给定正则表达式的每个子字符串获得* 用给定的[替换]。**…

一个芯片工程师的ADC学习笔记 (二)

众所周知&#xff0c;ADC主要用于对模拟信号进行数字采集&#xff0c;以进行数据处理。我们周围的信号一般都是不断变化的模拟量&#xff0c;如光、温度、速度、压力、声音等。然而&#xff0c;我们大多数人都使用数字设备。如果我们想方便地使用和处理信息&#xff0c;就需要将…

【机器学习】关联规则挖掘算法 + 三大案例实战 + Apriori算法 + Python代码实现

文章目录一、关联规则概述1.1 关联规则引入1.2 关联规则相关概念介绍1.2.1 样本、事务、项集、规则1.2.2 支持度、置信度1.2.3 提升度1.2.4 所有指标的公式二、Python实战关联规则2.1 使用 mlxtend 工具包得出频繁项集与规则2.1.1 安装 mlxtend 工具包2.1.2 引入相关库2.1.3 自…

MP3解码算法原理解析

一&#xff1a;MP3编解码整体结构介绍 看懵逼了是吧。这里面有很多概念需要一一讲解。 比特流&#xff1a;比特流是一种内容分发协议。它采用高效的软件分发系统和点对点技术共享大体积文件&#xff08;如一部电影或电视节目&#xff09;&#xff0c;并使每个用户像网络重新分配…

记录--微信调用jssdk--Invalid Signature, updateAppMessageShareData: denied等问题

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 最近在做安卓内嵌入H5活动页拉新活动&#xff0c;遇到的棘手问题记录下&#xff0c; 一是为了日后遇到同样问题好回顾&#xff0c;二是希望能帮到有同样问题的兄弟。 废话不多说&#xff0c;先从最棘手…