【计算机视觉】图像分割与特征提取——基于Log、Canny的边缘检测

news2024/11/23 0:12:26

8420b26844034fab91b6df661ae68671.png

个人简介: 

> 📦个人主页:赵四司机
> 🏆学习方向:JAVA后端开发 
> ⏰往期文章:SpringBoot项目整合微信支付
> 🔔博主推荐网站:牛客网 刷题|面试|找工作神器
> 📣种一棵树最好的时间是十年前,其次是现在!
> 💖喜欢的话麻烦点点关注喔,你们的支持是我的最大动力。

前言:

实验中要求能够自行评价Log、Canny算子在无噪声条件下和噪声条件下的分割性能。能够掌握分割条件(阈值等)的选择。完成规定图像的处理并要求正确评价处理结果,能够从理论上作出合理的解释。通过实验体会一些主要的分割算子对图像处理的效果,以及各种因素对分割效果的影响。

目录

一:相关概念

1.一阶导数二阶导数在图像边缘中的应用 

2.边缘检测基本步骤

3.好的边缘检测遵循的原则

4.二阶微分(差分)算子

二:拉普拉斯算子

1.等效式

2.拉普拉斯算子

​​​​3.拉普拉斯算子缺点 

三:高斯-拉普拉斯算子(Log)

1.相关概念

2.Log边缘检测

(1)基本特征

(2) 代码实战

(3)结果分析

四:Canny边缘检测

1.相概念

2.检测步骤

3.代码实战

4.结果分析 

五:思考总结


一:相关概念

1.一阶导数二阶导数在图像边缘中的应用 

  • 一阶导数可以用于检测图像中的一个点是否是边缘点(判断一个点是否在斜坡上);
  • 二阶导数可以用于判断一个边缘像素是在边缘亮的一边还是暗的一边。 

2.边缘检测基本步骤

  1. 滤波:边缘检测算法主要是基于图像强度的一阶和二阶导数,但导数的计算对噪声很敏感,因此必须使用滤波器来改善与噪声有关的边缘检测器的性能.需要指出,大多数滤波器在降低噪声的同时也导致了边缘强度的损失,因此,增强边缘和降低噪声之间需要折衷。
  2. 增强:增强边缘的基础是确定图像各点邻域强度的变化值.增强算法可以将邻域(或局部)强度值有显著变化的点突显出来.边缘增强一般是通过计算梯度幅值来完成的。
  3. 检测:在图像中有许多点的梯度幅值比较大,而这些点在特定的应用领域中并不都是边缘,所以应该用某种方法来确定哪些点是边缘点.最简单的边缘检测判据是梯度幅值阈值判据。
  4. 定位:如果某一应用场合要求确定边缘位置,则边缘的位置可在子像素分辨率上来估计,边缘的方位也可以被估计出来 

3.好的边缘检测遵循的原则

  • 有好的检测率:

    •  最优的检测器应该能检测出所有真实边缘,而忽略噪声和其他瑕疵

  • 有好的局部化效果:

    •  检测到的边缘必须尽可能的靠近真实边缘

    • 对于每个真实边缘点,检测器必须返回一个点

4.二阶微分(差分)算子

        如果所求的一阶导数高于某一阈值,则确定该点为边缘点,这样做会导致检测的边缘点太多。 一种更好的方法就是求梯度局部最大值对应的点,并认定它们是边缘点,通过去除一阶导数中的非局部最大值,可以检测出更精确的边缘。 一阶导数的局部最大值对应着二阶导数的零交叉点。这样,通过找图像强度的二阶导数的零交叉点就能找到边缘点。

二:拉普拉斯算子

1.等效式

   

2.拉普拉斯算子

    

  • 二阶微分关心的是图像灰度的突变而不强调灰度缓慢变化的区域,对边缘的定位能力更强。
  •  Laplace算子是各项同性的,即具有旋转不变性

​​​​3.拉普拉斯算子缺点 

  • 拉普拉斯的二阶方向导数算子在机器视觉中并不常用, 因为任何包含有二阶导数的算子比只包含有一阶导数的算子更易受噪声的影响.甚至一阶导数很小的局部峰值也能导致二阶导数过零点.
  • 为了避免噪声的影响,必须采用特别有效的滤波方法.
  • 边缘的方向信息丢失。

三:高斯-拉普拉斯算子(Log)

1.相关概念

        Marr和Hildreth将高斯滤波和拉普拉斯边缘检测结合在一起,首先用高斯函数先进行低通滤波,然后利用拉普拉斯算子进行高通滤波并提取零交叉点,形成LoG(Laplacian of Gaussian)算法,也称之为拉普拉斯高斯算法. 

  

2.Log边缘检测

(1)基本特征

  • 平滑滤波器是高斯滤波器.
  • 采用拉普拉斯算子计算二阶导数.
  • 边缘检测判据是二阶导数零交叉点并对应一阶导数的较大峰值.
  • 使用线性内插方法在子像素分辨率水平上估计边缘的位置.  
  • 为什么使用高斯滤波器:
    • 逼近必须能够抑制噪声效应
    • 必须尽量精确地确定边缘的位置  
    • 但平滑去噪和边缘检测是一对矛盾,抑制噪声和边缘精确定位是无法同时得到满足的。应用高斯函数的一阶导数,在二者之间获得最佳的平衡。

(2) 代码实战

对图像加入不同噪声之后使用Log算子进行边缘检测:

I = rgb2gray(imread('image\room.tif'));
J=imnoise(f,'gaussian',0.1);

BW1 = edge(I,'log',0.004); % σ=2
BW2 = edge(J,'log',0.012,2); % σ=2
figure(1),subplot(121),imshow(J),title('gaussian = 0.1');
subplot(122),imshow(BW2);title('THRESH = 0.012 σ=2');
imshow(BW1);title('σ=2')

BW1 = edge(I,'log',0.004,3); % σ=3

figure, imshow(BW1);title('σ=3')

  

图3.4-1 Log算子(Sigma = 2)

  

图3.4-2 Log算子(Sigma = 3)

  

图3.4-3 Log算子(加入高斯0噪声,Sigma=2)

  

图3.4-4 Log算子(加入强度0.1高斯噪声,THRESH=0.01,Sigma=2)

  

图3.4-5 Log算子(加入强度0.1高斯噪声,THRESH=0.012,Sigma=2)

(3)结果分析

        Log算子我采用了matlab自带的函数进行实验,edge(I,'log',THRESH,SIGMA)

可以看到有两个参数,THRESH表示函数忽略所有强度不大于THRESH值的边缘,SIGMA作为LoG过滤器的标准差。

        LoG算子将高斯滤波和拉普拉斯边缘检测结合在一起,首先用高斯函数先进行低通滤波,然后利用拉普拉斯算子进行高通滤波并提取零交叉点。可以看到处理结果的图像边缘较平滑(见图3.4-1),是因为LoG算子不能检测边缘方向。而且在加入噪声之后,可以看到LoG算子对噪声十分敏感(见图3.4-3),不断调整参数,最终在参数THRESH=0.012,Sigma=2时得到较好的结果(见图3.4-5),但是还是损失了很多边缘信息。

四:Canny边缘检测

1.相概念

        Canny边缘检测是一种非常流行的边缘检测算法,计算机视觉中用得最广的边缘检测器,是John Canny在1986年提出的(发表在PAMI)。

        理论模型:加性噪声干扰的阶梯边缘(Step-Edge) Canny展示了高斯函数的一阶导紧密逼近最优化信噪比和局部化的边缘算子 

2.检测步骤

步骤1. 图像与高斯平滑滤波器卷积:

步2. 使用一阶有限差分计算偏导数阵列PQ

步骤3.  计算梯度幅值与方向角:

步骤4. 非极大值抑制(NMS ) :

    去掉幅值局部变化非极大的点.

    * 将梯度角离散为圆周的四个扇区之一,以便用3×3的窗口作抑制运算

   * 方向角离散化:

    

   * 抑制,得到新幅值图:

  

步骤5. 阈值化

取高低两个阈值作用于幅值图N[i,j],得到两个边缘图:高阈值和低阈值边缘图。连接高阈值边缘图,出现断点时,在低阈值边缘图中的8邻点域搜寻边缘点。

3.代码实战

% I = rgb2gray(imread('image\room.tif'));
% J=imnoise(I,'gaussian',0);
% BW1 = edge(I,'canny',0.1);
% BW2 = edge(J,'canny',0.175,1.9);
% figure(2),subplot(121),imshow(J),title('加入gaussian噪声原图');
% figure(2),subplot(122),imshow(BW2),title('加入gaussian噪声后检测结果');
% figure(1),subplot(121),imshow(I),title('原图');
% subplot(122),imshow(BW1);title('自带函数Canny边缘检测');



% 自编程实现canny算子
% image = rgb2gray(imread('image\lena.png'));
% image=imnoise(image,'gaussian',0);
image = imread('image\figure.png');
image = rgb2gray(image);
subplot(221);
imshow(image);
title('原始图像');
image = double(image)/256;
[m,n] = size(image);
w = fspecial('gaussian');
image_1 = imfilter(image,w,'replicate');
subplot(222);
imshow(int8(256*image_1));
title('高斯滤波后的图像');

% 梯度计算
op = fspecial('sobel')/4;  % 用Sobel算子来求导数
x = op';
y =op;
bx = imfilter(image_1,x,'replicate');
by = imfilter(image_1,y,'replicate');
b_abs = sqrt(bx.*bx+by.*by);        % 求梯度的幅值
b_angle = angle(by-1i*bx);
b_ang = b_angle/3.1416*180;         % 求梯度的方向

% 梯度方向确定
dir=ones(m,n);
for r = 1:m
    for c = 1:n
        if((b_ang(r,c)>=22.5 && b_ang(r,c)<67.5)|| (b_ang(r,c)>=-157.5 && b_ang(r,c)<-112.5))
            dir(r,c) = 1;
        elseif ((b_ang(r,c)>=67.5 && b_ang(r,c)<112.5)|| (b_ang(r,c)>=-112.5 && b_ang(r,c)<-67.5))
            dir(r,c) = 2;
         elseif ((b_ang(r,c)>=112.5 && b_ang(r,c)<157.5)|| (b_ang(r,c)>=-67.5 && b_ang(r,c)<-22.5))
            dir(r,c) = 3;
        else
            dir(r,c) = 0;
        end
    end
end

% 遍历图像(抑制非极大值)
b_ab = [zeros(m,1),b_abs,zeros(m,1)];    % 串联矩阵
b_ab = [zeros(1,n+2);b_ab;zeros(1,n+2)];
b1=ones(m,n);
for r = 2:m+1
    for c = 2:n+1
        switch dir(r-1,c-1)
            case 0
                if((b_ab(r,c)<b_ab(r+1,c))|| (b_ab(r,c)<b_ab(r-1,c)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
            case 1
                if((b_ab(r,c)<b_ab(r+1,c-1))|| (b_ab(r,c)<b_ab(r-1,c+1)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
            case 2
                if((b_ab(r,c)<b_ab(r,c-1))|| (b_ab(r,c)<b_ab(r,c+1)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
            case 3
                if((b_ab(r,c)<b_ab(r-1,c-1))|| (b_ab(r,c)<b_ab(r+1,c+1)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
        end
    end
end

% 高阈值保留
b2=ones(m,n);
for r = 1:m
    for c = 1:n
        if (b1(r,c)>0.5)
            b2(r,c) = 0;
        else
            b2(r,c) = 1;
        end
    end
end

% 低阈值舍弃
b3=ones(m,n);
for r = 1:m
    for c = 1:n
        if(b1(r,c)<0.08)
            b3(r,c) = 1;
        else
            b3(r,c) = 0;
        end
    end
end

% 介于高低阈值之间
image_2 = b2;
for r = 2:m-1
    for c = 2: n-1
        if (image_2(r,c)== 1 && (b3(r,c)==0||b3(r+1,c)==0 ...
            ||b3(r+1,c-1)==0||b3(r+1,c+1)==0||b3(r,c-1)==0 ...
            ||b3(r,c+1)==0||b3(r-1,c-1)==0||b3(r-1,c)==0 ...
            ||b3(r-1,c+1)==0))
            image_2(r,c) = 0;
        else
            image_2(r,c) = 1;
        end
    end
end

%去除黑边
image_2(1,:) = 1;
image_2(m,:) = 1; 
image_2(:,1) = 1;
image_2(:,n) = 1;

subplot(223);
imshow(image_2);
title('Canny算子检测后的图像');

4.结果分析 

  

图3.5-1 Matlab自带canny函数检测结果

图3.5-2 Matlab自带canny函数检测加入高斯噪声图像结果 

图3.5-3 自编程实现canny算子检测结果

  

图3.5-4 自编程实现canny算子检测加入高斯噪声图像结果

        Canny算子能够有效地抑制噪声,且其根据信噪比与定位比乘积进行测度,得到最优化逼近算子,能较精确确定边缘的位置。类似于LoG边缘检测方法,Canny也属于先求平滑后求导数的方法。Canny边缘检测算法可以简化为四个步骤:

步骤1:用高斯滤波器平滑处理原图像;
步骤2:用一阶偏导的有限差分进行计算梯度的幅值和方向;
步骤3:对梯度幅值进行非极大值抑制;
步骤4:用双阈值算法检测和连接边缘

        使用平滑滤波的原因从根本上来说是边缘检测算子中的导数计算。导数计算对噪声十分敏感,如果不提前使用滤波器加以改善,则在导数计算后,噪声将会被放大,使得检测出来的虚假边缘变多,不利于边缘的提取。但是平滑滤波虽然能有效抑制噪声,但是会使得图像边缘模糊,增加了边缘检测的不确定性,但是噪声带来的影响更大,因此首先应考虑去除噪声。图像的边缘有方向和幅度两个属性,沿边缘方向像素变化平缓,垂直于边缘方向像素变化剧烈,边缘上的这种变化可以用微分算子检测出来,通常用一阶或二阶导数来检测边缘。在这里选用一阶导数来检测边缘,即求一阶导数最大值。设M(x,y)代表幅值,当其取得局部最大值时,其对应的梯度方向θ(x,y)反映了边缘的方向(边缘方向与梯度方向垂直)。得到全局梯度之后,还不能确定边缘,还需要保留局部梯度最大的点,且还要抑制非极大值,即将非局部最大值的像素点置为0。这就需要利用梯度的方向,与领域像素的梯度幅值进行比较,在程序中我采用的是3*3的窗口做抑制运算,对每个像素点与沿着梯度方向的两个八领域像素的梯度进行比较,最后选取梯度值最大的点。这样就基本排除了非边缘信息,仅仅保留了一些细的线条,即候选边缘。最后还需要采用双阈值法来检测和连接边缘,将高于高阈值的像素点保留,将低于低阈值的像素点排除,若高阈值图像边缘出现0值像素点,则判断该像素点低阈值图像8领域空间的像素是否存在高于高阈值的像素,如果存在则该像素被保留(像素值置为1),否则被排除,至此就实现了Canny边缘检测。

        从实验结果(见图3.5-3)来看,Canny算子检测出来的边缘信息更准确,显示出来的边缘线条较细。且在加入噪声之后,由于前面利用平滑滤波过滤了噪声,最后得到的边缘检测结果也还是较满意的(见图3.5-4),但是由于原图像有些边缘周围的像素值较小,且变化较平缓,例如屋顶区域,在进行平滑滤波时容易将边缘信息抹除,故最终检测结果屋顶部分的边缘便消失了。

五:思考总结

1)评价一下Roberts 算子、Prewitt 算子、Sobel 算子对于噪声条件下边界检测的性能。

        从上面的检测结果来看,Roberts算子采用的是2*2的模板,对噪声比较敏感,对有噪声的图像处理能力不强;而Prewitt算子采用的是3*3的模板,其抗噪能力要强一些,但是效果也不是很理想;对于Sobel算子,其在Prewitt算子升增加了权重的概念,具有平滑噪声的作用,因此其对有噪声图像的边缘检测能力要比另外两个算子强。

2)为什么LoG梯度检测算子的处理结果不需要象Prewitt 等算子那样进行幅度组合?

        因为LoG算子采用拉普拉斯算子计算二阶导数,且边缘检测判据是二阶导数零交叉点并对应一阶导数的较大峰值,还使用线性内插方法在子像素分辨率水平上估计边缘的位置。

3)实验中所使用的四种算子所得到的边界有什么异同?

        Roberts、Prewitt、Sobel算子得到的边缘信息较粗,定位都不是很准确,而LoG算子得到的边缘信息定位较准确,且得到的边缘线条较细。对于有噪声的图像,Roberts、Prewitt、LoG算子都对噪声比较敏感,处理能力一般,而Sobel算子能对噪声进行平滑,其对噪声图片的边缘检测要比另外三个好。

4)比较边缘提取中LOG、Canny算子的边缘提取效果。

        相同尺度下的LOG算子总是能比Canny算子检测出更多的细节,Canny算子能对真正比较显著地边缘给出检测。LOG算子容易受尺度的影响,不同尺度下的边缘点要用不同尺度的LOG算子检测,Canny 算子受尺度的影响不太明显,不同尺度下,边缘点的位置都有偏差,但几乎相同;从对噪声的敏感程度来看,LOG边缘检测子是采用二阶导数过零点的检测方法,故对噪声更敏感一些,因此从抑制噪声方面来讲,Canny边缘检测子不容易受到噪声的干扰,而相同尺度下LOG算子却容易受到噪声的干扰,抑制噪声的能力要弱一些。LOG算子对噪声的抑制能力随着尺度的增加而增加,相同尺度下的Canny算子比LOG算子的抗噪声能力强,而LOG算子比Canny算子的边缘点准确;对于弱边缘,由于Canny边缘检测子采用两种不同的阈值分别检测强边缘和弱边缘,并且当弱边缘和强边缘相连时,才将弱边缘包含在输出图像中,故而Canny算子更能检测出真正的弱边缘,但是Canny边缘检测子检测出的边缘的位置会有一定范围的误差;对于假边缘,LOG边缘检测子相对比较容易受到噪声干扰,会检测出更多的细节,也容易检测出一些由于噪声引起的假边缘,但是LOG边缘检测子对边缘位置的检测还是很准确的。

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

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

相关文章

回归算法|长短期记忆网络LSTM及其优化实现

本期文章将介绍LSTM的原理及其优化实现 序列数据有一个特点&#xff0c;即“没有曾经的过去则不存在当前的现状”&#xff0c;这类数据以时间为纽带&#xff0c;将无数个历史事件串联&#xff0c;构成了当前状态&#xff0c;这种时间构筑起来的事件前后依赖关系称其为时间依赖&…

雨云游戏云面板服使用教程我的世界Forge服务端开服教程(翼龙面板)

雨云面板服目前支持一键开服的游戏有&#xff1a;Minecraft Java版、Minecraft 基岩版、泰拉瑞亚、饥荒&#xff0c;还提供纯Java/Linux环境&#xff08;Docker&#xff09;&#xff0c;方便开自己开其他游戏服。 其中Minecraft Java版支持一键开服的有Arclight、Mohist、CatS…

Python基于微博的舆情分析、热搜可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 1. 简介 基于Python Django的微博热搜、微博舆论可视化系统。通过微博舆情分析系统获取到最新微博舆情分析…

Day13力扣打卡

打卡记录 奖励最顶尖的 k 名学生(哈希表排序) 用哈希表对所有的positive与negative词条进行映射&#xff0c;然后遍历求解。tip&#xff1a;常用的分割字符串的操作&#xff1a;1.stringstream配合getline() [格式buf, string, char]2.string.find()[find未找到目标会返回npos…

51单片机-串口

电脑与单片机通过串口交互 设置波特率&#xff08;根据这个代码&#xff0c;去配置urt_Init()&#xff09; 参照上面配置下面这个&#xff0c;然后删掉上面这个代码 使用SUBF进行发送&#xff0c;TI0代表结束&#xff0c;结束后需要复位 下载、打开串口&#xff0c;设置波特率…

AutoCAD 2022安装及激活

下载好AutoCAD2022安装文件后&#xff0c;直接解压&#xff0c;会看到这个名字的安装文件AutoCAD_2022_Simplified_Chinese_Win_64bit_dlm.sfx&#xff0c;我们双击打开就会进入安装过程。 安装文件需要自解压&#xff0c;我们默认到C盘就可以了&#xff0c;这些文件我们在安装…

exFAT文件系统的目录与文件存储

目录与文件存储的差异 在exFAT文件系统中&#xff0c;目录和文件的存储方式是不同的。 目录和文件都是以簇&#xff08;Cluster&#xff09;为单位进行存储&#xff0c;但它们的数据结构和用途不同。 目录的存储&#xff1a;目录&#xff08;子目录&#xff09;是用于组织和管…

linux入门---多线程的控制

目录标题 线程库pthread_create如何一次性创建多个线程线程的终止线程的等待线程取消分离线程如何看待其他语言支持的多线程线程id的本质线程的局部存储线程的封装 线程库 要想控制线程就得使用原生线程库也可以将其称为pthread库&#xff0c;这个库是遵守posix标准的&#xf…

Servlet 与Spring对比!

前言&#xff1a; Spring相关的框架知识&#xff0c;算是目前公司在用的前沿知识了&#xff0c;很重要&#xff01;&#xff01; 那么以Spring为基础的框架有几个&#xff1f; 以Spring为基础的框架包括若干模块&#xff0c;其中主要的有Spring Framework、Spring Boot、Spring…

三十八、【进阶】最左前缀法则

1、理解 最左前缀法则&#xff0c;如果索引了多列(联合索引)&#xff0c;要遵守最左前缀法则&#xff0c;最左前缀法则是致&#xff0c;查询从索引的最左列开始&#xff0c;并且不跳过索引中的列。 如果跳过某一列&#xff0c;索引将部分失效(该索引后面的字段索引全部失效)。 …

锐捷EG易网关 phpinfo.view.php 信息泄露

致未经身份验证获取敏感信息 访问漏洞url&#xff1a; /tool/view/phpinfo.view.php漏洞证明&#xff1a; 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝赐教&#xff0c;万分感谢。 免责声明&#xff1a;由于传播或利用此文所提供的信息、技术或方法而造成的任何…

代码签名证书如何申请

代码签名证书也称之为软件数字证书&#xff0c;也可以叫作微软信任证书&#xff0c;主要给软件进行身份确定及保护知识产权&#xff0c;也可以被操作系统给信&#xff0c;对于软件开发企业是一项最基本的产品之一。 代码签名证书分为OV和EV两种类型&#xff0c;虽然认证步骤大同…

爬取抖音用户的个人基本信息

今年夏季&#xff0c;大概七八月份&#xff0c;刀郎开通抖音账号&#xff0c;并在抖音上发布多首作品&#xff0c;一时之间其热度暴涨&#xff0c;其粉丝也是与日俱增。 有人为了蹭热度&#xff0c;直播刀郎粉丝的实时变化情况&#xff0c;直播热度最高的时候同时几千人在线观…

SpringBoot内置工具类之断言Assert的使用与部分解析

先例举一个service的demo中用来验证参数对象的封装方法&#xff0c;使用了Assert工具类后是不是比普通的 if(xxx) { throw new RuntimeException(msg) } 看上去要简洁多了&#xff1f; 断言Assert工具类简介 断言是一个判断逻辑&#xff0c;用来检查不该发生的情况&#xff…

红队专题-从零开始VC++C/S远程控制软件RAT-MFC-远控介绍及界面编写

红队专题 招募六边形战士队员[1]远控介绍及界面编写1.远程控制软件演示及教程简要说明主程序可执行程序 服务端生成器主机上线服务端程序 和 服务文件管理CMD进程服务自启动主程序主对话框操作菜单列表框配置信息 多线程操作非模式对话框 2.环境&#xff1a;3.界面编程新建项目…

MD5加密后16位与32位的区别 [ 详细 ]

文章目录 前言MD5加密算法说明MD516位和32位有何区别关于MD5的一些常见问题1、使用MD5对密码加密有什么用&#xff1f;2、为什么通过md5.cn在线加解密站还能解出明文呢&#xff1f; 总结 前言 MD5是HASH函数的一种&#xff0c;HASH函数又称杂凑函数&#xff0c;是在信息安全领…

Spark新特性与核心概念

一、Sparkshuffle &#xff08;1&#xff09;Map和Reduce 在shuffle过程中&#xff0c;提供数据的称之为Map端&#xff08;Shuffle Write&#xff09;&#xff0c;接受数据的称之为Redeuce端&#xff08;Shuffle Read&#xff09;&#xff0c;在Spark的两个阶段中&#xff0c;总…

C语言_断言assert详解

一、assert定义 assert() 的用法像是一种"契约式编程"&#xff0c;在我的理解中&#xff0c;其表达的意思就是&#xff0c;程序在我的假设条件下&#xff0c;能够正常良好的运作&#xff0c;其实就相当于一个 if 语句&#xff1a; if(假设成立) {程序正常运行&…

PYTHON+CH341 3线SPI驱动UC1601 LCD实现汉字显示

前言 参考大佬用CH341驱动OLED,链接如下&#xff1a;GitHub - jimjiang2/ch341dll_wrap_typical_app: A ch341dll Wrap is for using in Python 32bits windows to access I2C SPI and MDIO (by GPIO), and Demo with display PC sreen on OLED by i2c or SPI . 本文主要实现了…

C++设计模式_17_Mediator 中介者

Mediator 中介者也是属于“接口隔离”模式。 文章目录 1. 动机 (Motivation)2. 模式定义3. 结构(Structure)4. 要点总结5. 其他参考 1. 动机 (Motivation) 在软件构建过程中&#xff0c;经常会出现多个对象互相关联交互的情况&#xff0c;对象之间常常会维持一种复杂的引用关系…