OpenCV 从入门到精通(day_05)

news2025/4/8 19:18:26

1. 模板匹配

1.1 什么是模板匹配

        模板匹配就是用模板图(通常是一个小图)在目标图像(通常是一个比模板图大的图片)中不断的滑动比较,通过某种比较方法来判断是否匹配成功。

1.2 匹配方法

        res=cv2.matchTemplate(image, templ, method)

  • image:原图像,这是一个灰度图像或彩色图像(在这种情况下,匹配将在每个通道上独立进行)。

  • templ:模板图像,也是灰度图像或与原图像相同通道数的彩色图像。

  • method:匹配方法,可以是以下之一:

    • cv2.TM_CCOEFF

    • cv2.TM_CCOEFF_NORMED

    • cv2.TM_CCORR

    • cv2.TM_CCORR_NORMED

    • cv2.TM_SQDIFF

    • cv2.TM_SQDIFF_NORMED

    • 这些方法决定了如何度量模板图像与原图像子窗口之间的相似度。

  • 返回值res

    函数在完成图像模板匹配后返回一个结果矩阵,这个矩阵的大小与原图像相同。矩阵的每个元素表示原图像中相应位置与模板图像匹配的相似度。

    匹配方法不同,返回矩阵的值的含义也会有所区别。以下是几种常用的匹配方法及其返回值含义:

    1. cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED

      返回值越接近0,表示匹配程度越好。最小值对应的最佳匹配位置。

    2. cv2.TM_CCORRcv2.TM_CCORR_NORMED

      返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

    3. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

      返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

1.2.1 平方差匹配

        cv2.TM_SQDIFF:以模板图与目标图所对应的像素值使用平方差公式来计算,其结果越小,代表匹配程度越高,计算过程举例如下。
        注意:模板匹配过程皆不需要边缘填充,直接从目标图像的左上角开始计算。

1.2.2 归一化平方差匹配

        cv2.TM_SQDIFF_NORMED:与平方差匹配类似,只不过需要将值统一到0到1,计算结果越小,代表匹配程度越高,计算过程举例如下。

1.2.3 相关匹配

        cv2.TM_CCORR:使用对应像素的乘积进行匹配,乘积的结果越大其匹配程度越高,计算过程举例如下。

1.2.4 归一化相关匹配

        cv2.TM_CCORR_NORMED:与相关匹配类似,只不过是将其值统一到0到1之间,值越大,代表匹配程度越高,计算过程举例如下。

1.2.5 相关系数匹配

        cv2.TM_CCOEFF:需要先计算模板与目标图像的均值,然后通过每个像素与均值之间的差的乘积再求和来表示其匹配程度,1表示完美的匹配,-1表示最差的匹配,计算过程举例如下。

1.2.6 归一化相关系数匹配

        cv2.TM_CCOEFF_NORMED:也是将相关系数匹配的结果统一到0到1之间,值越接近1代表匹配程度越高,计算过程举例如下。

1.3 绘制轮廓

        找的目标图像中匹配程度最高的点,我们可以设定一个匹配阈值来筛选出多个匹配程度高的区域。
        loc=np.where(array > 0.8) :loc包含array中所有大于0.8的元素索引的数组;
        zip(*loc)

第1节知识示例:

import cv2 as cv
import numpy as np

# x = list([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
# print(list(zip(*x)))
game = cv.imread('images/game.png')  # 目标图
temp = cv.imread('images/temp.png')  # 模板图
game_gray = cv.cvtColor(game, cv.COLOR_BGR2GRAY)
temp_gray = cv.cvtColor(temp, cv.COLOR_BGR2GRAY)
# print(game_gray.shape)
# print(temp_gray.shape)

# 获取模板图的宽高
shape_t = temp_gray.shape
h, w = shape_t

# 模板匹配cv.matchTemplate(目标图,模板图,匹配方法),返回匹配程度的矩阵
res = cv.matchTemplate(game_gray, temp_gray, cv.TM_CCOEFF_NORMED)
# print(res, "---", res.shape)
# 设定阈值
thresh = 0.8
# 找符合条件的值的坐标
loc = np.where(res >= thresh)  # 返回值中,第一个列表中装的是y值,另一个装的是x值;可以理解为坐标值
# print(list(zip(*loc[::-1])))
# print(type(loc))  # tuple

# 获取点坐标
for pt in zip(*loc[::-1]):
    # print(pt)
    cv.rectangle(game, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 1)

cv.imshow('game', game)
cv.waitKey(0)
cv.destroyAllWindows()

2. 霍夫变换

2.1 理解霍夫变换

        霍夫变换常用来提取图像中的直线和圆等几何形状。

2.2 霍夫直线变换

        对于一条直线(不垂直于x轴的直线),都可以用$y=k x+b$来表示,此时,x和y是横纵坐标,k和b是一个固定参数。当我们换一种方式来看待这个式子,我们就可以得到:

        此时,以k和b    为横纵坐标,x和y为固定参数,变换如下图所示:

        从上图可以看出,在直角坐标系下的一个直线,在变换后的空间中仅仅表示为一点,对于变换后的空间,我们称其为霍夫空间。也就是说,直角坐标系下的一条直线对应了霍夫空间中的一个点。类似的,霍夫空间中的一条直线也对应了直角坐标系中的一个点,如下图所示:

        那么对于一个二值化后的图形来说,其中的每一个目标像素点(这里假设目标像素点为白色像素点)都对应了霍夫空间的一条直线,当霍夫空间中有两条直线相交时,就代表了直角坐标系中某两个点所构成的直线。而当霍夫空间中有很多条线相交于一点时,说明直角坐标系中有很多点能构成一条直线,也就意味着这些点共线,因此我们就可以通过检测霍夫空间中有最多直线相交的交点来找到直角坐标系中的直线。
        然而对于x=1这种直线来说,y已经不存在了,那么就没办法使用上面的方法进行检测了,为了解决这个问题,我们就将直角坐标系转化为极坐标系,然后通过极坐标系与霍夫空间进行相互转化。
 

        在极坐标系下是一样的,极坐标中的点对于霍夫空间中的线,霍夫空间中的点对应极坐标中的直线。并且此时的霍夫空间不再是以k为横轴、b为纵轴,而是以为θ横轴、ρ(上图中的r)为纵轴。上面的公式中,x、y是直线上某点的横纵坐标(直角坐标系下的横纵坐标),和是极坐标下的坐标,因此我们只要知道某点的x和y的坐标,就可以得到一个关于θ-ρ的表达式,如下图所示:

        根据上图,霍夫空间在极坐标系下,一点可以产生一条三角函数曲线,而多条这样的曲线可能会相交于同一点。因此,我们可以通过设定一个阈值,来检测霍夫空间中的三角函数曲线相交的次数。如果一个交点的三角函数曲线相交次数超过阈值,那么这个交点所代表的直线就可能是我们寻找的目标直线。
        使用API:lines=cv2.HoughLines(image, rho, theta, threshold)

  • image:输入图像,通常为二值图像,其中白点表示边缘点,黑点为背景。

  • rho:r的精度,以像素为单位,表示霍夫空间中每一步的距离增量, 值越大,考虑越多的线。

  • theta:角度θ的精度,通常以弧度为单位,表示霍夫空间中每一步的角度增量。值越小,考虑越多的线。

  • threshold:累加数阈值,只有累积投票数超过这个阈值的候选直线才会被返回。

返回值:cv2.HoughLines 函数返回一个二维数组,每一行代表一条直线在霍夫空间中的参数 (rho, theta)
        示例:

import cv2 as cv
import numpy as np

img = cv.imread('images/huofu.png')
shape = img.shape
# 边缘检测
dst = cv.Canny(img, 30, 70)  # 返回值边缘检测后的图像
# cv.imshow('canny', dst)
# 使用霍夫变换检查测直线,返回值是[[rho, theta]],角度单位是弧度
lines = cv.HoughLines(dst, 0.8, np.pi / 180, 90)  # 检测到四条直线
# print(lines)
# 绘制直线
for line in lines:
    rho, theta = line[0]  # 获取rho(直线到原点的垂直距离)和theta(直线与 x 轴的夹角)
    sin_theta = np.sin(theta)
    print(rho, sin_theta)
    cos_theta = np.cos(theta)
    x1 = 0
    y1 = int(rho / sin_theta)
    print(x1, y1)
    x2 = shape[1]
    y2 = int((rho - x2 * cos_theta) / sin_theta)
    cv.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1)

cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()

2.3 统计概率霍夫直线变换

        前面的方法又称为**标准霍夫变换**,它会计算图像中的每一个点,计算量比较大,另外它得到的是整一条线(r和θ),并不知道原图中直线的端点。所以提出了**统计概率霍夫直线变换**(Probabilistic Hough Transform),是一种改进的霍夫变换,它在获取到直线之后,会检测原图中在该直线上的点,并获取到两侧的端点坐标,然后通过两个点的坐标来计算该直线的长度,通过直线长度与最短长度阈值的比较来决定该直线要不要被保留。
        使用API:lines=cv2.HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=0, maxLineGap=0)

  • image:输入图像,通常为二值图像,其中白点表示边缘点,黑点为背景。

  • rho:极径分辨率,以像素为单位,表示极坐标系中的距离分辨率。

  • theta:极角分辨率,以弧度为单位,表示极坐标系中角度的分辨率。

  • threshold:阈值,用于过滤掉弱检测结果,只有累计投票数超过这个阈值的直线才会被返回。

  • lines(可选):一个可初始化的输出数组,用于存储检测到的直线参数。

  • minLineLength(可选):最短长度阈值,比这个长度短的线会被排除。

  • maxLineGap(可选):同一直线两点之间的最大距离。当霍夫变换检测到一系列接近直角的线段时,这些线段可能是同一直线的不同部分。maxLineGap参数指定了在考虑这些线段属于同一直线时,它们之间最大可接受的像素间隔。

    • 如果maxLineGap设置得较小,那么只有相邻且间距很小的线段才会被连接起来,这可能导致检测到的直线数量较多,但更准确地反映了图像中的局部直线结构。

    • 如果maxLineGap设置得较大,则线段间的间距可以更大,这样可能会合并更多的局部线段成为更长的直线,但有可能会将原本不属于同一直线的线段误连接起来。

返回值lines:cv2.HoughLinesP 函数返回一个二维数组,每个元素是一个包含4个元素的数组,分别表示每条直线的起始点和结束点在图像中的坐标(x1, y1, x2, y2)。
        示例:

import cv2 as cv
import numpy as np

img = cv.imread('images/huofu.png')
shape = img.shape
# 边缘检测
dst = cv.Canny(img, 30, 70)  # 返回值边缘检测后的图像
# 统计概率霍夫直线变换
lines = cv.HoughLinesP(dst, 0.8, np.pi / 180, 90, minLineLength=50, maxLineGap=10)
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1)

cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()

2.4 霍夫圆变换

        霍夫圆变换跟直线变换类似,它可以从图像中找出潜在的圆形结构,并返回它们的中心坐标和半径。只不过线是用(r,θ)表示,圆是用(x_center,y_center,r)来表示,从二维变成了三维,数据量变大了很多;所以一般使用霍夫梯度法减少计算量。
        使用API:circles=cv2.HoughCircles(image, method, dp, minDist, param1, param2)

  • image:输入图像,通常是灰度图像。

  • method:使用的霍夫变换方法:霍夫梯度法,可以是 cv2.HOUGH_GRADIENT,这是唯一在OpenCV中用于圆检测的方法。

  • dp:累加器分辨率与输入图像分辨率之间的降采样比率,用于加速运算但不影响准确性。设置为1表示霍夫梯度法中累加器图像的分辨率与原图一致

  • minDist:检测到的圆心之间的最小允许距离,以像素为单位。在霍夫变换检测圆的过程中,可能会检测到许多潜在的圆心。minDist 参数就是为了过滤掉过于接近的圆检测结果,避免检测结果过于密集。当你设置一个较小的 minDist 值时,算法会尝试找出尽可能多的圆,即使是彼此靠得很近的圆也可能都被检测出来。相反,当你设置一个较大的 minDist 值时,算法会倾向于只检测那些彼此间存在一定距离的独立的圆。

    例如,如果你设置 minDist 很小,可能在真实图像中存在的一个大圆旁边的一些噪声点会被误判为多个小圆;而如果设置 minDist 较大,则可以排除这种情况,只保留明显分离的圆的检测结果。

  • param1param2:这两个参数是在使用 cv2.HOUGH_GRADIENT 方法时的特定参数,分别为:

    • param1(可选):阈值1,决定边缘强度的阈值。

    • param2:阈值2,控制圆心识别的精确度。较大的该值会使得检测更严格的圆。param2 通常被称为圆心累积概率的阈值。在使用霍夫梯度方法时,param2 设置的是累加器阈值,它决定了哪些候选圆点集合被认为是有效的圆。较高的 param2 值意味着对圆的检测更严格,只有在累加器中积累了足够高的响应值才认为是真实的圆;较低的 param2 值则会降低检测的门槛,可能会检测到更多潜在的圆,但也可能包含更多的误检结果。

      举个例子,如果你将 param2 设置得较高,那么算法只会返回那些边缘强烈符合圆形特征且周围有足够的支持像素的圆;而如果设置得较低,即使边缘特征不是很强烈,只要有一些证据支持就可能将其视为一个圆。

        返回值:cv2.HoughCircles 返回一个二维numpy数组,包含了所有满足条件的圆的参数。
        示例:

import cv2 as cv
import numpy as np

img = cv.imread('images/huofu.png')
shape = img.shape
# 边缘检测
dst = cv.Canny(img, 30, 70)  # 返回值边缘检测后的图像
# 霍夫圆变换
circles = cv.HoughCircles(dst, cv.HOUGH_GRADIENT, 1, 20, param2=30)
# print(circles)
# 循环、遍历、绘制圆
for circle in circles:
    x, y, r = circle[:][0].astype(int)
    # print(x, y, r)
    cv.circle(img, (x, y), r, (0, 255, 0), 2)

cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()

3. 图像亮度变换

        我们知道,图像都是由一个个像素值组成的,图像的亮度变换实际上还是图像像素值的变换。

3.1 亮度变换

        在讲解亮度时,需要和对比度一起来进行解释。
        对比度调整:图像暗处像素强度变低,图像亮处像素强度变高,从而拉大中间某个区域范围的显示精度。
        亮度调整:图像像素强度整体变高或者变低。

        上图中:
                (a) 把亮度调高,就是图片中的所有像素值加上了一个固定值;
                (b) 把亮度调低,就是图片中的所有像素值减去了一个固定值;
                (c) 增大像素对比度(白的地方更白,黑的地方更黑);
                (d) 减小像素对比度(整幅图都趋于一个颜色);
        OpenCV调整图像对比度和亮度时,公式为:g(i,j)=\alpha f(i,j)+\beta。但是不能浅显的讲\alpha是控制对比度,\beta是控制亮度的。
        对比度:需要通过\alpha\beta一起控制(仅调整\alpha只能控制像素强度0附近的对比度,而这种做法只会导致像素强度大于0的部分更亮而已,根本看不到对比度提高的效果)。
        亮度:通过\beta控制。

3.2 线性变换

        使用 cv2.addWeighted() 函数,可以对图像的像素值进行加权平均,进而改变图像的整体亮度。亮度增益可以通过向每个像素值添加一个正值来实现。

        cv2.addWeighted(src1, alpha, src2, beta, gamma)

  • src1:第一张输入图像,它将被赋予权重 alpha

  • alpha:第一个输入图像的权重。

  • src2:第二张输入图像,它将被赋予权重 beta

  • beta:第二个输入图像的权重。

  • gamma:一个标量,将被添加到权重求和的结果上,可用于调整总体亮度。

    计算公式为: dst = src1 * alpha + src2 * beta + gamma

        示例:

import cv2 as cv
import numpy as np

img = cv.imread('images/1.jpg')
img2 = np.zeros_like(img)

img_n = cv.addWeighted(img, 1.5, img2, 0, 0)
cv.imshow('img', img)
cv.imshow('img_n', img_n)
cv.waitKey(0)
cv.destroyAllWindows()

3.3 直接像素值修改

        如果只需要增加或减少固定的亮度值,可以直接遍历图像像素并对每个像素值进行加减操作。
        使用的API:numpy.clip(a, a_min, a_max)
        
用于对数组中的元素进行限定,将超出指定范围的元素值截断至指定的最小值和最大值之间

  • a:输入数组。

  • a_min:指定的最小值,数组中所有小于 a_min 的元素将被替换为 a_min

  • a_max:指定的最大值,数组中所有大于 a_max 的元素将被替换为 a_max

示例:

import cv2 as cv
import numpy as np

# 为滑动条添加窗口
winname = 'Trackbar_win'  # 窗口名
cv.namedWindow(winname)  # 为滑条创建的窗口


def change(x):  # x是像素值的变化量
    # 把值映射到(-255, 255)
    x = x / 255 * (255 - (-255)) - 255
    # print(x)  # -55
    # 读取图像
    img = cv.imread('images/1.jpg')
    img_new = np.uint8(np.clip(img + x, 0, 255))  # 原像素值加上一个像素值,变化后的像素值范围是0-255
    cv.imshow('img', img)
    cv.imshow('img_new', img_new)


maxval = 255  # 滑条最大值
trackval = 100  # 滑条初始值
change(trackval)
# 创建滑条cv.createTrackbar(滑条名, 显示滑条的窗口名, 滑条初始值, 滑条的最大值, 关联函数)
cv.createTrackbar('Trackbar', winname, trackval, maxval, change)
cv.waitKey(0)
cv.destroyAllWindows()

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

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

相关文章

OpenRouter开源的AI大模型路由工具,统一API调用

简介 ‌OpenRouter是一个开源的路由工具‌,它可以绕过限制调用GPT、Claude等国外模型。以下是对它的详细介绍: 一、主要功能 OpenRouter专注于将用户请求智能路由到不同的AI模型,并提供统一的访问接口。它就像一个“路由器”,能…

zabbix监控网站(nginx、redis、mysql)

目录 前提准备: zabbix-server主机配置: 1. 安装数据库 nginx主机配置: 1. 安装nginx redis主机配置: 1. 安装redis mysql主机配置: 1. 安装数据库 zabbix-server: 1. 安装zabbix 2. 编辑配置文…

蓝桥杯冲刺

例题1&#xff1a;握手问题 方法1&#xff1a;数学推理(简单粗暴&#xff09; 方法2&#xff1a;用代码实现方法1 #include<iostream> using namespace std; int main() {int result 0;for (int i 1; i < 49; i){for (int j i 1; j < 50; j){//第i个人与第j个…

Spring Security(maven项目) 3.1.0

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

C# 从代码创建选型卡+表格

private int tabNum 1; private int sensorNum 5; private void InitializeUI() {// 创建右侧容器面板Panel rightPanel new Panel{Dock DockStyle.Right,Width 300,BackColor SystemColors.ControlDark,Parent this};// 根据防区数量创建内容if (tabNum &g…

OpenCV 从入门到精通(day_02)

1. 边缘填充 为什么要填充边缘呢&#xff1f;我们以下图为例&#xff1a; 可以看到&#xff0c;左图在逆时针旋转45度之后原图的四个顶点在右图中已经看不到了&#xff0c;同时&#xff0c;右图的四个顶点区域其实是什么都没有的&#xff0c;因此我们需要对空出来的区域进行一个…

Ceph异地数据同步之-RBD异地同步复制(上)

#作者&#xff1a;闫乾苓 文章目录 前言基于快照的模式&#xff08;Snapshot-based Mode&#xff09;工作原理单向同步配置步骤单向同步复制测试双向同步配置步骤双向同步复制测试 前言 Ceph的RBD&#xff08;RADOS Block Device&#xff09;支持在两个Ceph集群之间进行异步镜…

【C++】STL库_stack_queue 的模拟实现

栈&#xff08;Stack&#xff09;、队列&#xff08;Queue&#xff09;是C STL中的经典容器适配器 容器适配器特性 不是独立容器&#xff0c;依赖底层容器&#xff08;deque/vector/list&#xff09;通过限制基础容器接口实现特定访问模式不支持迭代器操作&#xff08;无法遍历…

一周学会Pandas2 Python数据处理与分析-编写Pandas2 HelloWord项目

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们首先准备一个excel文件&#xff0c;用来演示pandas操作数据集(数据的集合)。excel文件属于数据集的一种&#xf…

【易订货-注册/登录安全分析报告】

前言 由于网站注册入口容易被机器执行自动化程序攻击&#xff0c;存在如下风险&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露&#xff0c;不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 &#xff0c;造成用户无法登陆、注册&#xff0c;大量收到垃圾短信的…

如何在Windows上找到Python安装路径?两种方法快速定位

原文&#xff1a;如何在Windows上找到Python安装路径&#xff1f;两种方法快速定位 | w3cschool笔记 在 Windows 系统上找到 Python 的安装路径对于设置环境变量或排查问题非常重要。本文将介绍两种方法&#xff0c;帮助你找到 Python 的安装路径&#xff1a;一种是通过命令提…

lvgl避坑记录

一、log调试 #if LV_USE_LOG && LV_LOG_LEVEL > LV_LOG_LEVEL_INFOswitch(src_type) {case LV_IMG_SRC_FILE:LV_LOG_TRACE("lv_img_set_src: LV_IMG_SRC_FILE type found");break;case LV_IMG_SRC_VARIABLE:LV_LOG_TRACE("lv_img_set_src: LV_IMG_S…

element-plus中,表单校验的使用

目录 一.案例1&#xff1a;给下面的表单添加校验 1.目的要求 2.步骤 ①给需要校验的el-form-item项&#xff0c;添加prop属性 ②定义一个表单校验对象&#xff0c;里面存放了每一个prop的检验规则 ③给el-form组件&#xff0c;添加:rules属性 ④给el-form组件&#xff0…

PyTorch复现线性模型

【前言】 本专题为PyTorch专栏。从本专题开始&#xff0c;我将通过使用PyTorch编写基础神经网络&#xff0c;带领大家学习PyTorch。并顺便带领大家复习以下深度学习的知识。希望大家通过本专栏学习&#xff0c;更进一步了解人更智能这个领域。 材料来源&#xff1a;2.线性模型_…

Kafka+Zookeeper从docker部署到spring boot使用完整教程

文章目录 一、Kafka1.Kafka核心介绍&#xff1a;​核心架构​核心特性​典型应用 2.Kafka对 ZooKeeper 的依赖&#xff1a;3.去 ZooKeeper 的演进之路&#xff1a;注&#xff1a;&#xff08;本文采用ZooKeeper3.8 Kafka2.8.1&#xff09; 二、Zookeeper1.核心架构与特性2.典型…

RK3568驱动 SPI主/从 配置

一、SPI 控制器基础配置(先说主的配置&#xff0c;后面说从的配置) RK3568 集成高性能 SPI 控制器&#xff0c;支持主从双模式&#xff0c;最高传输速率 50MHz。设备树配置文件路径通常为K3568/rk356x_linux_release_v1.3.1_20221120/kernel/arch/arm64/boot/dts/rockchip。 …

【全队项目】智能学术海报生成系统PosterGenius--风格个性化调整

​ &#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#x1f3c0;大模型实战训练营 ​&#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 1.前言 PosterGenius致力于开发一套依托DeepSeek…

【系统移植】(六)第三方驱动移植

【系统移植】&#xff08;六&#xff09;第三方驱动移植 文章目录 【系统移植】&#xff08;六&#xff09;第三方驱动移植1.编译驱动进内核方法一&#xff1a;编译makefile方法二&#xff1a;编译kconfig方法三&#xff1a;编译成模块 2.字符设备框架 编译驱动进内核a. 选择驱…

STM32实现一个简单电灯

新建工程的步骤 建立工程文件夹&#xff0c;Keil中新建工程&#xff0c;选择型号工程文件夹里建立Start、Library、User等文件夹&#xff0c;复制固件库里面的文件到工程文件夹工程里对应建立Start、Library、User等同名称的分组&#xff0c;然后将文件夹内的文件添加到工程分组…

【shiro】shiro反序列化漏洞综合利用工具v2.2(下载、安装、使用)

1 工具下载 shiro反序列化漏洞综合利用工具v2.2下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1kvQEMrMP-PZ4K1eGwAP0_Q?pwdzbgp 提取码&#xff1a;zbgp其他工具下载&#xff1a; 除了该工具之外&#xff0c;github上还有其他大佬贡献的各种工具&#xff0c;有…