当前位置: 首页 > news >正文

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)图像变换

形态变换

图像处理中的形态学操作是处理图像结构的有效方法。以下是一些常见的形态学操作的介绍及其在 OpenCV 中的实现示例。

1. 腐蚀(Erosion)

腐蚀操作通过消除图像边界来减少图像中的白色区域(前景),使物体的边界向内收缩。它的作用是去除小的噪点。根据内核的大小,边界附近的所有像素都将被丢弃。因此,前景对象的厚度或大小在图像中减少或只是白色区域减少。它有助于消除小的白色噪音,分离两个连接的对象等。

import cv2
import numpy as np# 读取图像
image = cv2.imread('f:/apple.jpg', 0)
# 定义腐蚀的内核
kernel = np.ones((5,5), np.uint8)
# 进行腐蚀操作  
eroded = cv2.erode(image, kernel, iterations=1)cv2.imshow('Eroded Image', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 膨胀(Dilation)

膨胀操作与腐蚀相反,主要是增加图像中的白色区域,使物体的边界向外扩展。

# 进行膨胀操作  
dilated = cv2.dilate(image, kernel, iterations=1)  cv2.imshow('Dilated Image', dilated)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

3. 开运算(Opening)

开运算是先进行腐蚀再进行膨胀,用于去除小的噪声,并保持图像中物体的形状和大小。

# 进行开运算  
opened = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)  cv2.imshow('Opened Image', opened)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

4. 闭运算(Closing)

闭运算是先进行膨胀再进行腐蚀,主要用于填补图像中的小孔洞或黑色区域。

# 进行闭运算  
closed = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)  cv2.imshow('Closed Image', closed)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

5. 形态梯度(Morphological Gradient)

形态梯度是图像膨胀与腐蚀之间的差异,用于提取边缘。

# 进行形态梯度  
gradient = cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel)  cv2.imshow('Morphological Gradient', gradient)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

6. 顶帽(Top Hat)

顶帽运算是原图像与开运算结果的差,主要用于突出比周围区域亮的部分。

# 进行顶帽运算  
tophat = cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel)  cv2.imshow('Top Hat', tophat)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

7. 黑帽(Black Hat)

黑帽运算是闭运算结果与原图像的差,主要用于突出比周围区域暗的部分。

# 进行黑帽运算  
blackhat = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)  cv2.imshow('Black Hat', blackhat)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

几何变换

缩放

缩放是调整图片的大小。 OpenCV 使用cv.resize()函数进行调整。可以手动指定图像的大小,也可以指定比例因子。可以使用不同的插值方法。

import numpy as np
import cv2 as cv
img = cv.imread('image.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)

平移变换
平移变换是物体位置的移动。转换矩阵:

t_x,t_y是方向的偏移量,可以将变换矩阵存为 np.float32 类型的 numpy 数组,并将其作为 cv.warpAffine 的第二个参数。cv.warpAffine 函数的第三个参数是输出图像的大小,其形式应为(宽度、高度)。记住宽度=列数,高度=行数。

import numpy as np
import cv2 as cv
img = cv.imread('image.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()

旋转

旋转矩阵:

但 Opencv 提供了可变旋转中心的比例变换,所以你可以在任意位置旋转图片,修改后的转换矩阵为:

例如旋转90度:

img = cv.imread('image.jpg',0)
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))

仿射变换
在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。仿射变换是图像处理和计算机视觉中的一种重要技术,用于执行图像的几何变换。它保留了点、直线和面之间的相对位置关系,因此常用于图像的旋转、缩放、平移和倾斜等操作。

仿射变换包括:

  1. 平移(Translation):图像中的每个点沿着 x 和 y 轴移动指定的距离。
  2. 缩放(Scaling):根据指定的比例因子缩放图像的大小。
  3. 旋转(Rotation):绕图像中心点旋转一定的角度。
  4. 倾斜(Shearing):沿 x 或 y 方向对图像进行剪切或倾斜。

结合这些操作,可以通过仿射矩阵来实现任意的仿射变换。仿射变换的矩阵形式可以表示为:

在 OpenCV 中,使用 cv2.warpAffine 函数执行仿射变换。下面是一个示例,展示如何进行平移、缩放和旋转:

import cv2
import numpy as np# 读取图像
image = cv2.imread('f:/apple.jpg')# 获取图像的尺寸
rows, cols, _ = image.shape# 定义仿射变换矩阵
# 这里定义一个平移和缩放的组合
# 平移 tx = 50,ty = 30;缩放 sx = 1.5,sy = 1.5(增加 50%)
M = np.float32([[1.5, 0, 50],[0, 1.5, 30]])# 应用仿射变换
dst = cv2.warpAffine(image, M, (int(cols * 1.5), int(rows * 1.5)))# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

综合仿射变换

下面是一个完成平移、缩放和旋转组合的仿射变换示例:

import cv2
import numpy as np# 读取图像
image = cv2.imread('f:/apple.jpg')
# 获取图像的中心
center = (image.shape[1] // 2, image.shape[0] // 2)# 定义旋转角度和缩放因子
angle = 45  # 旋转 45 度
scale = 1.0 # 不缩放  # 获取仿射变换矩阵
M = cv2.getRotationMatrix2D(center, angle, scale)# 应用仿射变换
transformed = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', transformed)
cv2.waitKey(0)
cv2.destroyAllWindows()

透视变换
透视变换是一种将图像中某个区域进行变形的技术,使得该区域看起来像从不同的角度观看。透视变换通过将图像中的四个点映射到另一个四边形区域来实现,这样就能够模拟真实世界中由于相机角度变化而引起的视觉变化。

对透视转换,你需要一个 3x3 变换矩阵。即使在转换之后,直线也将保持直线。

要找到这个变换矩阵,需要输入图像上的 4 个点和输出图像上的相应点。在这四点中,任意三点不应该共线。


​在 OpenCV 中,透视变换使用 cv2.getPerspectiveTransform 函数来计算透视变换矩阵,然后用 cv2.warpPerspective 函数应用该变换。
 

import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('f:/apple.jpg')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()# 读取图像
image = cv2.imread('f:/apple.jpg')# 获取图像的尺寸
height, width = image.shape[:2]# 定义源图像中的四个点(例如,选择四个角点)
pts1 = np.float32([[100, 100], [200, 100], [100, 200], [200, 200]])
# 定义目标图像中的四个点
pts2 = np.float32([[80, 80], [220, 100], [90, 210], [210, 220]])# 计算透视变换矩阵
M = cv2.getPerspectiveTransform(pts1, pts2)# 应用透视变换
warped_image = cv2.warpPerspective(image, M, (width, height))# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Warped Image', warped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

频域变换:傅里叶变换和拉普拉斯变换

Numpy具有FFT软件包进行傅里叶变换。np.fft.fft2() 为我们提供了频率转换。它的第一个参数是输入灰度图像。第二个参数是可选的,它决定输出数组的大小。如果它大于输入图像的大小,则在计算FFT之前用零填充输入图像。如果小于输入图像,将裁切输入图像。如果未传递任何参数,则输出数组的大小将与输入的大小相同。 

使用 NumPy 执行图像的傅里叶变换(FFT)和反傅里叶变换(IFFT):

1. 傅里叶变换(FFT)

np.fft.fft2() 用于计算二维傅里叶变换,适合处理灰度图像。你可以传递一个可选的大小参数来决定输出数组的形状。

2. 逆傅里叶变换(IFFT)

np.fft.ifft2() 用于计算二维逆傅里叶变换,将频域数据转换回时域。

import numpy as np
import cv2
import matplotlib.pyplot as plt# 读取灰度图像
image = cv2.imread('f:/apple.jpg', cv2.IMREAD_GRAYSCALE)# 执行傅里叶变换
# 参数为 image 的 shape 可以控制零填充大小
f_transform = np.fft.fft2(image)# 对傅里叶变换结果进行移位,使得低频部分居中
f_transform_shifted = np.fft.fftshift(f_transform)# 计算幅度谱,以便可视化
magnitude_spectrum = np.log(np.abs(f_transform_shifted) + 1)  # 避免 log(0)# 执行逆傅里叶变换
# 首先对移位后的频域图像进行逆变换
inverse_transform_shifted = np.fft.ifftshift(f_transform_shifted)
recovered_image = np.fft.ifft2(inverse_transform_shifted)# 取实部作为恢复的图像
recovered_image = np.abs(recovered_image)# 显示原始图像、幅度谱和恢复的图像
plt.figure(figsize=(12, 12))plt.subplot(1, 3, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')
plt.axis('off')plt.subplot(1, 3, 2)
plt.title('Magnitude Spectrum')
plt.imshow(magnitude_spectrum, cmap='gray')
plt.axis('off')plt.subplot(1, 3, 3)
plt.title('Recovered Image')
plt.imshow(recovered_image, cmap='gray')
plt.axis('off')plt.tight_layout()
plt.show()

OpenCV中的傅立叶变换
OpenCV 为此提供了功能 cv.dft() 和 cv.idft() 。它返回与以前相同的结果,但是有两个通道。第一个通道将具有结果的实部,第二个通道将具有结果的虚部。输入的图像应首先转换为np.float32 。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 读取图像
img = cv.imread('f:/apple.jpg', 0)# 1. 计算傅里叶变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)# 2. 计算幅度谱
magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))# 3. 创建掩码,然后将掩码应用于傅里叶变换结果
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2# 创建一个掩码,中心区域为1,其余区域为0(高通滤波器)
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1  # 中心区域为1# 应用掩码
fshift = dft_shift * mask# 4. 计算逆傅里叶变换
f_ishift = np.fft.ifftshift(fshift)  # 反移位
img_back = cv.idft(f_ishift)  # 逆傅里叶变换
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])  # 获取复数的幅度# 5. 显示原图、傅里叶变换幅度谱和恢复后的图像
plt.figure(figsize=(12, 6))# 原始图像
plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Input Image')
plt.xticks([]), plt.yticks([])# 幅度谱
plt.subplot(1, 3, 2)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum')
plt.xticks([]), plt.yticks([])# 恢复后的图像
plt.subplot(1, 3, 3)
plt.imshow(img_back, cmap='gray')
plt.title('Recovered Image')
plt.xticks([]), plt.yticks([])plt.tight_layout()  # 自动调整子图参数
plt.show()

拉普拉斯算子是高通滤波器,Sobel是HPF。只需对Laplacian进行傅立叶变换,以获得更大的FFT大小。四种常用算子:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt# 简单平均滤波器(不带缩放参数)
mean_filter = np.ones((3, 3))# 创建高斯滤波器
x = cv.getGaussianKernel(5, 10)
gaussian = x * x.T# 不同的边缘检测滤波器
# Scharr滤波器(x方向)
scharr = np.array([[-3, 0, 3],[-10, 0, 10],[-3, 0, 3]])# Sobel滤波器(x方向)
sobel_x = np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])# Sobel滤波器(y方向)
sobel_y = np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]])# 拉普拉斯滤波器
laplacian = np.array([[0, 1, 0],[1, -4, 1],[0, 1, 0]])# 将所有滤波器放入列表中
filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
filter_name = ['mean_filter', 'gaussian', 'laplacian', 'sobel_x', 'sobel_y', 'scharr']# 计算每个滤波器的傅里叶变换
fft_filters = [np.fft.fft2(f) for f in filters]
fft_shift = [np.fft.fftshift(y) for y in fft_filters]# 计算每个滤波器的幅度谱
mag_spectrum = [np.log(np.abs(z) + 1) for z in fft_shift]# 绘制幅度谱
plt.figure(figsize=(12, 6))
for i in range(6):  # 使用 range 代替 xrangeplt.subplot(2, 3, i + 1)plt.imshow(mag_spectrum[i], cmap='gray')plt.title(filter_name[i])plt.xticks([]), plt.yticks([])plt.tight_layout()  # 调整子图参数
plt.show()

相关文章:

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)图像变换

形态变换 图像处理中的形态学操作是处理图像结构的有效方法。以下是一些常见的形态学操作的介绍及其在 OpenCV 中的实现示例。 1. 腐蚀(Erosion) 腐蚀操作通过消除图像边界来减少图像中的白色区域(前景),使物体的边…...

Spark SQL中的from_json函数详解

Spark SQL中的from_json函数详解 在Spark SQL中,from_json是一个用于解析JSON数据的函数,主要用于将JSON格式的字符串解析为结构化的数据(即StructType或其他Spark SQL数据类型)。这个函数在处理半结构化数据(如JSON日…...

【软件架构】软件的十二种架构简介

软件的十二种架构简介 一、软件的12种架构 1. 单体架构 (Monolithic Architecture)2. 分层架构 (Layered Architecture)3. 事件驱动架构 (Event-Driven Architecture)4. 微服务架构 (Microservices Architecture)5. 服务导向架构 (Service-Oriented Architecture, SOA)6. 客户…...

日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件

日历热力图,月度数据可视化图表,vue组件 先看效果👇 在线体验https://www.guetzjb.cn/calanderViewGraph/ 日历图简单划分为近一年时间,开始时间是 上一年的今天,例如2024/01/01 —— 2025/01/01,跨度刚…...

Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制

在Vue 3中,导航守卫(Navigation Guard)用于拦截路由的变化,可以在用户访问页面前进行检查。结合Axios进行token认证机制时,我们可以通过导航守卫在路由跳转时,检查用户的认证状态,确保用户有有效…...

【爬虫】使用 Scrapy 框架爬取豆瓣电影 Top 250 数据的完整教程

前言 在大数据和网络爬虫领域,Scrapy 是一个功能强大且广泛使用的开源爬虫框架。它能够帮助我们快速地构建爬虫项目,并高效地从各种网站中提取数据。在本篇文章中,我将带大家从零开始使用 Scrapy 框架,构建一个简单的爬虫项目&am…...

一分钟学习数据安全——白盒加密及安当应用

白盒加密作为一种先进的加密技术,在数据安全、通信安全和信息隐私保护等多个关键领域都有应用。这次的一分钟,让您快速了解一下白盒加密的概念,以及安当产品中的白盒加密应用。 一、什么是白盒加密 简单来说,白盒加密是一种特殊…...

composer安装指定php版本, 忽略平台原因导致的报错

windows下 //composer安装指定php版本, 写出完整的php和composer.phar路径 D:\phpstudy_pro\Extensions\php\php8.1.11nts\php.exe D:\phpstudy_pro\Extensions\composer1.8.5\composer.phar install windows下一些扩展不支持, 如下图, 所以本地composer安装组件时可以忽略 …...

Java 前端详解

Java 前端详解 Java 前端开发主要涉及使用 Java 相关技术和框架来创建用户界面和处理用户交互。虽然 Java 原本是后端开发的主力语言,但它也提供了许多前端开发工具和框架。以下是 Java 前端开发的主要内容和技术栈。 一、Java 前端技术栈 Java Swing 和 AWT AWT (…...

鸿蒙安装HAP时提示“code:9568344 error: install parse profile prop check error” 问题现象

在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install parse profile prop check error”错误信息。 解决措施 该问题可能是由于应用使用了应用特权,但应用的签名文件发生变化后未将新的签名指纹重新配置到设备的特权管控白名…...

Javaweb之css

css的三种引入方式 1内行式 2.内嵌式 3.外部样式表 内行式和内嵌式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...

实施工程师:面试基础宝典

一.运维工程师和实施工程师的区别&#xff1a;工作内容不同、职能不同、工作形式不同 1.工作内容不同&#xff1a; 运维工程师要对公司硬件和软件进行维护。 硬件包括&#xff1a;机房、机柜、网线光纤、PDU、服 务器、网络设备、安全设备等。 实施工程师包括常用操作系统、应…...

react install

react 安装 React 是一个用于构建用户界面的 JavaScript 库。以下是安装 React 的步骤&#xff1a; 使用 Create React App Create React App 是一个官方支持的命令行工具&#xff0c;用于快速搭建 React 应用。 安装 Node.js 和 npm 确保你的计算机上安装了 Node.js 和 npm…...

ElasticSearch DSL查询之排序和分页

一、排序功能 1. 默认排序 在 Elasticsearch 中&#xff0c;默认情况下&#xff0c;查询结果是根据 相关度 评分&#xff08;score&#xff09;进行排序的。我们之前已经了解过&#xff0c;相关度评分是通过 Elasticsearch 根据查询条件与文档内容的匹配程度自动计算得出的。…...

uniapp封装websocket

WebSocket介绍 后端使用的是springbootnetty做websocket的服务端&#xff0c;参考我其他博文 项目使用场景 开发uniapp项目时&#xff0c;需要进行实时通信&#xff0c;比如聊天等。需要封装一个工具类&#xff0c;统一对socket进行管理。 uniapp websocket官方文档&#xff1…...

【Linux】18.Linux进程控制(2)

文章目录 3. 进程程序替换3.1 单进程版 -- 看看程序替换3.2 替换原理3.3 替换函数函数解释命名理解 3.4 多进程版 -- 验证各种程序替换接口3.5 自定义shell 3. 进程程序替换 3.1 单进程版 – 看看程序替换 makefile mycommand:mycommand.cgcc -o $ $^ -stdc99 .PHONY:clean …...

reactor框架使用时,数据流请求流程

1. 我们在Flux打开时&#xff0c;可以看到 public abstract class Flux<T> implements CorePublisher<T> { 2. public interface CorePublisher<T> extends Publisher<T> {void subscribe(CoreSubscriber<? super T> subscriber); } Publish…...

读西瓜书的数学准备

1&#xff0c;高等数学&#xff1a;会求偏导数就行 2&#xff0c;线性代数&#xff1a;会矩阵运算就行 参考&#xff1a;线性代数--矩阵基本计算&#xff08;加减乘法&#xff09;_矩阵运算-CSDN博客 3&#xff0c;概率论与数理统计&#xff1a;知道啥是随机变量就行...

摄像头模块如何应用在宠物产品领域

一、宠物监控类产品 家庭宠物远程监控摄像头 1.基本功能与原理&#xff1a;这类摄像头可以通过 Wi - Fi 连接到家庭网络&#xff0c;主人可以使用手机应用程序在任何有网络连接的地方查看宠物的实时画面。摄像头模块内置有图像传感器&#xff0c;能够捕捉光线并将其转换为数字…...

c++学习第七天

创作过程中难免有不足&#xff0c;若您发现本文内容有误&#xff0c;恳请不吝赐教。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考。 一、const成员函数 //Date.h#pragma once#include<iostream> using namespace std;class Date { public:Date…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...