FPGA与Matlab图像处理之直方图均衡化

文章目录

  • 一、什么是直方图?
  • 二、什么是直方图均衡化?
  • 三、Matlab实现直方图均衡化的步骤
    • 第一步: 彩色图像转成灰度图像
    • 第二步:提取亮度通道的直方图
    • 第三步:累计亮度通道的像素值频率
    • 第四步: 映射到新的灰度值
  • 四、Verilog实现直方图均衡化
    • 第一步:Verilog实现彩色图像转灰度图像
      • 4.1.1Verilog代码
      • 4.1.2 仿真截图
    • 第二步:Verilog实现统计累计灰度直方图
      • 4.2.1 verilog代码
      • 4.2.2 仿真结果
    • 第三步:Verilog实现直方图均衡化
      • 4.3.1 Verilog代码
      • 4.3.2 仿真结果


一、什么是直方图?

  在前文《Verilog和Matlab实现RGB888互转YUV444》中我们知道,人眼对亮度的敏感度要大于色度的敏感度,图像的直方图是用来表示图像中像素亮度或颜色分布的一种图形表示方法。它通过统计图像中每个亮度值(或颜色值)出现的频率,如下图所示:

在这里插入图片描述
  X轴表示亮度的范围;对于8色深的图像,亮度范围就是0-255 ,Y轴表示每亮度下所拥有的像素数量。在图像处理中,直方图的作用有:

  • 对比度调整:通过分析直方图,可以了解图像的对比度,并进行相应的调整。
  • 图像增强:可以使用直方图均衡化等技术来改善图像的视觉效果。
  • 特征提取:在图像处理和计算机视觉中,直方图可以作为特征之一,用于图像分类、识别等任务。
  • 分析图像质量:通过观察直方图,可以识别图像是否存在过曝或欠曝等问题。

  如上面这张原始图片我们可以看出整体画面比较明亮,直方图显示各灰阶的数量都比较均衡,接下来我们看另一张图片的直方图:

在这里插入图片描述
  我们可以看到这幅图整体画面比较暗,在直方图上面体现出来就是像素数量比较集中在左侧,相反我们也可也通过观测一张图片的直方图来大致判断这副图片的整体明暗程度。

二、什么是直方图均衡化?

  直方图均衡化是一种经典的图像处理算法,用以改善图像的亮度和对比度。如果一副图片整体偏暗,灰度值大致分布在较低的范围内;图像进行直方图均衡化后会使其原本分布集中在低范围色阶的像素值,均衡的分布到所有可取值的范围,这样,图像就既有明亮也有灰暗,对比度和亮度就得到了改善,直方图均衡化的作用:

  1. 增强对比度:直方图均衡化通过重新分配图像的亮度值,使得图像的亮度范围更加均匀。这可以显著提高图像的对比度,使得细节更加清晰,特别是在原始图像对比度较低的情况下。
  2. 改善细节可见性:通过均衡化,暗部和亮部的细节会更加明显。这对于医学影像、卫星图像等需要清晰细节的应用非常重要。
  3. 去除光照不均:在某些情况下,图像可能由于光照条件不均而出现阴影或亮斑。均衡化可以帮助减轻这些问题,使得图像更加均匀。
  4. 增强特征提取:在计算机视觉和图像分析中,均衡化后的图像能更好地突出特征,使得后续的特征提取和分类任务更加有效。
  5. 提高图像质量:在某些情况下,直方图均衡化可以改善图像的整体视觉质量,使得图像在不同显示设备上表现得更加一致。

在这里插入图片描述
  上面就是将一张整体偏暗的图片均衡化后的效果。可以看出,均衡化后的图片一些细节都显示出来了,均衡化后的直方图也比较均匀,我们也可以转成灰度图片来观察:

在这里插入图片描述
  在实际实现过程中,就是要先将彩色图片转换成灰度图片后,在做均衡化处理,因为直方图均衡化只对亮度Y进行处理,对于色彩通道的Cb、Cr是不做处理的,这就是直方图均衡化的作用。

三、Matlab实现直方图均衡化的步骤

第一步: 彩色图像转成灰度图像

  上文可以知道,直方图均衡化是对亮度进行操作的,因此我们处理图像时候,先将彩色图片转换成灰度图片,使得RGB三个分量的值都变成YYY,这样操作图像的数据就只是操作了亮度Y,颜色数据我们保留,彩色转灰度图像在matlab可以直接调用:

I = rgb2gray(RGB)

整体代码如下:

% 读取彩色图像
img = imread('....\....\....\...\.....bmp');% 将彩色图像转换为灰度图像
grayImg = rgb2gray(img);% 原图像
subplot(1, 2, 1);
imshow(img);
title('原始图像');% 灰度图像
subplot(1, 2, 2);
imshow(grayImg);
title('灰度图像');

在这里插入图片描述

第二步:提取亮度通道的直方图

  统计图像亮度通道各色阶中像素的个数,为后续做均衡化做准备,在matlab中直接调用:

[counts,binLocations] = imhist(I)  %计算灰度图像 I 的直方图。imhist 函数在 counts 中返回直方图计数,在 binLocations 中返回 bin 位置。直方图中 bin 的数量由图像类型确定。

整体代码如下:

% 读取彩色图像
img = imread('...\....\.....\.....\....bmp');% 将彩色图像转换为灰度图像
grayImg = rgb2gray(img);% 计算灰度图像的直方图
[counts, grayLevels] = imhist(grayImg);% 原图像
subplot(1, 3, 1);
imshow(img);
title('原始图像');% 灰度图像
subplot(1, 3, 2);
imshow(grayImg);
title('灰度图像');% 原始直方图
subplot(1, 3, 3);
bar(grayLevels, counts);
title('原始图像的直方图');
xlim([0 255]);

在这里插入图片描述

第三步:累计亮度通道的像素值频率

  统计每一个灰度在原始图像上的像素所占总体的比例,例如一共有100个像素值,其中第26色阶有15个像素点,那么25色阶上的像素值频率 = 15/100 = 0.15 ,现在我们将每个色阶对应的频率都累加起来,可以得到一个最高值1 ;这也叫归一化累积分布函数(CDF)
  举个例子:现在我有一张图像总共有1024个像素点,每个像素点的灰阶都是一样的,那么对应每一色阶的数量都是1024/256=4个,对应的分布直方图如下所示:

在这里插入图片描述

  接下来要对灰度直方图进行归一化处理,也就是限制到[0:1]范围内。我们计算每个色阶中像素所占的总比,也叫做概率,即:每个色阶中像素的概率都是4/1024 = 0.00390625,则归一化后的直方图如下所示:

在这里插入图片描述
  接下来对归一化后的直方图进行累加,画出累计归一化累积分布函数(CDF),如下所示:

5在这里插入图片描述
  这就是一张灰度不变图像归一化后累积分布函数,最高累计值为100%=1 ,接下来我们画出任意一幅图的归一化后的累计分布函数图,matlab代码如下:

% 读取图像
img = imread('...\...\.....\....bmp'); % 将图像转换为灰度图像
grayImg = rgb2gray(img);% 计算灰度图像的直方图
[counts, grayLevels] = imhist(grayImg);% 计算累积分布函数(CDF)
cdf = cumsum(counts);
cdf_normalized = cdf / max(cdf);  % 归一化到 [0, 1] 范围% 显示结果
figure;% 原始图像
subplot(3, 1, 1);
imshow(img);
title('原始图像');% 亮度直方图
subplot(3, 1, 2);
bar(grayLevels, counts, 'FaceColor', [0.2, 0.6, 0.8]);
title('灰度图像直方图');
xlabel('像素数量');
ylabel('色阶');
xlim([0 255]);% 归一化累积分布函数
subplot(3, 1, 3);
plot(grayLevels, cdf_normalized, 'LineWidth', 2);
title('归一化累积分布函数 (CDF)');
xlabel('色阶');
ylabel('累计概率');
xlim([0 255]);
ylim([0 1]);  % 设置 y 轴范围为 [0, 1]
grid on;

在这里插入图片描述

  由此可见,理想情况下的归一化累计分布函数是一条斜直线,而实际的图片大多数都是这种不规则曲线,因此直方图均衡化的目的就是尽量把这种不规则曲线调成直线。

第四步: 映射到新的灰度值

  在得到归一化的 CDF 后,为了将其映射回原始图像的灰度级范围(0 到 255),需要将其乘以 255。具体来说:归一化的 CDF 值是一个小数,乘以 255 后,可以得到一个新的灰度值,范围在 0 到 255 之间。

  为什么要乘以255? 我们画出一副图像的归一化分布函数和灰度一致的图像归一化累计分布函数叠加:

在这里插入图片描述
  橙色曲线是实际图像的累计归一化分布函数,蓝色的为灰度一致的标准累计归一化分布函数,直方图均衡化的目的就是让橙色的曲线变成直线,具体步骤就是:

在这里插入图片描述

  假设这三个点的坐标如上所示,现在要把橙色图片变成直线,有两种方式:

  1. b点往上移动到a点
  2. c点往右移动到a点

  我们可以分析出来第一种方式是不可取的,因为b点的含义表示色阶为15的像素点占比0.13,如果把b点往上移动到0.3,就相当于把色阶为15的像素点数量增加了,那么像素点总共的数量是不变的,这增加的像素点是从哪里来?所以这样不可取。
  第二种方式就是把c点往左移到a点,含义就是色阶26的像素点占比0.3,把这占比0.3的像素点色阶变成15,这样的像素点占比依然是0.3,所以数量是没有变化的。具体公式就是
y = k x = 1 / 255 ∗ x y=kx=1/255 * x y=kx=1/255x

x = 255 ∗ y x = 255 * y x=255y
  matlab代码如下:

% 读取图像
img = imread('...\...\.....\....bmp'); % 将图像转换为灰度图像
grayImg = rgb2gray(img);% 计算灰度图像的直方图
[counts, grayLevels] = imhist(grayImg);% 计算累积分布函数(CDF)
cdf = cumsum(counts);
cdf_normalized = cdf / max(cdf);  % 归一化到 [0, 1] 范围% 进行直方图均衡化
equalizedImg = histeq(grayImg);% 计算均衡化后的直方图
[counts_eq, grayLevels_eq] = imhist(equalizedImg);% 计算均衡化后的累积分布函数(CDF)
cdf_eq = cumsum(counts_eq);
cdf_normalized_eq = cdf_eq / max(cdf_eq);  % 归一化到 [0, 1] 范围% 显示结果
figure;% 原始图像
subplot(3, 2, 1);
imshow(grayImg);
title('原始图像');% 原始图像的灰度直方图
subplot(3, 2, 2);
bar(grayLevels, counts);
title('原始图像的灰度直方图');
xlabel('色阶');
ylabel('像素数量');
xlim([0 255]);% 原始图像的归一化累积分布函数
subplot(3, 2, 3);
bar(grayLevels, cdf_normalized);
title('原始图像的归一化累积分布函数');
xlabel('色阶');
ylabel('累计概率');
xlim([0 255]);
ylim([0 1]);  % 设置 y 轴范围为 [0, 1]% 均衡化后的图像
subplot(3, 2, 4);
imshow(equalizedImg);
title('均衡化后的图像');% 均衡化后的灰度直方图
subplot(3, 2, 5);
bar(grayLevels_eq, counts_eq);
title('均衡化后的灰度直方图');
xlabel('色阶');
ylabel('像素数量');
xlim([0 255]);% 均衡化后的归一化累积分布函数
subplot(3, 2, 6);
bar(grayLevels_eq, cdf_normalized_eq);
title('均衡化后的归一化累积分布函数');
xlabel('色阶');
ylabel('累计概率');
xlim([0 255]);
ylim([0 1]);  % 设置 y 轴范围为 [0, 1]

在这里插入图片描述

四、Verilog实现直方图均衡化

第一步:Verilog实现彩色图像转灰度图像

  这部分和可以直接使用前文《Verilog和Matlab实现RGB888互转YUV444》这个模块,把G、B也换成Y即可,代码如下:

4.1.1Verilog代码

`timescale 1ns / 1ps
module rgb2gray(input                                               clk             ,input                                               rst             ,//输入RGB原始信号input                                               i_data_valid    ,input           [7:0]                               i_data_r        ,input           [7:0]                               i_data_g        ,input           [7:0]                               i_data_b        ,//输出转换后的灰度信号output                                              o_data_valid    ,output          [7:0]                               o_data_r        ,output          [7:0]                               o_data_g        ,output          [7:0]                               o_data_b        
);//Y= 0.299*R + 0.587*G + 0.114*B/****************parameter********************/
parameter   Y_PARA_R    = 306,   // 0.299*1024Y_PARA_G    = 601,   // 0.587*1024Y_PARA_B    = 117;   // 0.114*1024/*******************reg***********************/
reg     [1:0]   ro_data_valid   ;
reg     [17:0]  ro_data_r       ;
reg     [17:0]  r_y1            ;
reg     [17:0]  r_y2            ;
reg     [17:0]  r_y3            ;/******************wire***********************/
/******************assign*********************/
assign o_data_valid = ro_data_valid[1]     ;
assign o_data_r     = ro_data_r[17:10]     ;
assign o_data_g     = ro_data_r[17:10]     ;
assign o_data_b     = ro_data_r[17:10]     ;//1 clock
always @(posedge clk) beginr_y1 = (i_data_r * Y_PARA_R);r_y2 = (i_data_g * Y_PARA_G);r_y3 = (i_data_b * Y_PARA_B);
end//2 clock
always @(posedge clk) beginro_data_r = r_y1 + r_y2 + r_y3;
end//sync_validalways @(posedge clk) beginro_data_valid <= {ro_data_valid[0],i_data_valid};
endendmodule

4.1.2 仿真截图

在这里插入图片描述

在这里插入图片描述
  转换出来的灰度图像和matlab一致。

第二步:Verilog实现统计累计灰度直方图

  用matlab软件实现直方图的统计非常简单,调用一个函数即可。但是FPGA内没有这种函数,只能靠自己计算。实现的思想就是用一个双口RAM,简单双口和真双口都可以:

  • 第一步:把输入的灰度数据作为ram的读地址
  • 第二步:把读出来的数据 + 1
  • 第三步:再把+1后的数据写入相同地址

  需要注意的是,从给出读地址到数据读出来需要花费一个时钟周期,再写入到ram里面也需要花费一个时钟周期,因此当遇到两个连续灰度值一样时,可能会出现漏写。因此再写入ram之前还要判断当前灰度值是否一致,不一样的话就+1,一样的话就+2,连续三个一样的话就+3,以此类推。

4.2.1 verilog代码

  端口定义:

module histogram_stat#(parameter IMG_WIDTH     = 1920,         //输入图像宽度parameter IMG_HEIGHT    = 1280,         //输入图像高度parameter GRAY_LEVEL    = 256           //输入图像灰度等级
)
(input 	wire 			clk 		    ,  input	wire 			rst 		    , input 	wire 			i_hsync	        , //输入图像行同步信号input	wire 			i_vsync	        , //输入图像场同步信号input	wire 			i_data_valid	, //输入图像数据有效信号input 	wire 	[7:0]	i_data 	        , //输入灰度图像数据output 	wire 			o_histo_valid   , //输出累计直方图output 	wire 	[31:0]	o_histo_data	  //输出累计直方图数据  
);

  简单双口ram定义:

cal_ram u0_cal_ram (.clka (clk        ),      // input wire clka.wea  (wr_ram_en  ),      // input wire [0 : 0] wea.addra(wr_ram_addr),      // input wire [7 : 0] addra.dina (wr_ram_data),      // input wire [23 : 0] dina.clkb (clk        ),      // input wire clkb.addrb(rd_ram_addr),      // input wire [7 : 0] addrb.doutb(rd_ram_data)       // output wire [23 : 0] doutb
);

4.2.2 仿真结果

  先打开matlab看直方图和累积直方图以及每一个色阶的数量:

在这里插入图片描述

在这里插入图片描述

  色阶数量分别是:7798,557,14863,7908 …等等。

在这里插入图片描述
  累计直方图是:7798,8355,23218,31126…等等,我们打开仿真波形来观察:

在这里插入图片描述
  我们可以看到,ram从0-255存放的直方图灰度数量和matlab一致,我们接下来看累计直方图:

在这里插入图片描述  我们可以看到,累计直方图数量和matlab也一致,我们用模拟波形来观察:
在这里插入图片描述
  直方图波形和matlab也一致。

在这里插入图片描述
  累计直方图波形和matlab也一致。

第三步:Verilog实现直方图均衡化

  归一化分布函数就是把累计分布函数除以总像素,得到一个小数。由于FPGA不擅长除法,因此我们可以先扩大再右移,例如:

4.3.1 Verilog代码

module cal_cdf#(parameter IMG_WIDTH     = 1920,         //输入图像宽度parameter IMG_HEIGHT    = 1280         //输入图像高度
)
(input                                               clk ,input                                               rst ,input                                               i_histo_valid   ,       //输入累计直方图数据有效信号input           [31:0]                              i_histo_data    ,       //输入累计直方图数据input           [7:0]                               i_src_gray_data   ,     //输入原始灰度图像input                                               i_src_gray_data_valid , //输入原始灰度图像有效信号output  reg                                         o_post_cal_gray_data_valid  , //输出直方图均衡化的output          [23:0]                              o_post_cal_gray_data          //输出均衡化后的图像数据  
);/***************function**************//***************parameter*************/
parameter   const   = 36'd68451041280;   //255*2^28
parameter   cal_cdf = const / (IMG_WIDTH*IMG_HEIGHT);  //  255*2^28/(IMG_WIDTH*IMG_HEIGHT)  15bit

  我们先在上层定义好图像的长和宽,因为直方图均衡最重要的就是 x = 255 ∗ y x = 255 * y x=255y, 因此我们先定义好常数255 * 2^28 ,再除以总像素就得到了x, 再把新的灰度直方图写入到新的ram里,然后让原始灰度数据作为读ram地址,读出来的数值就是需要替换掉的灰度值。

4.3.2 仿真结果

  先来观察我们均衡化后的灰度直方图为:

在这里插入图片描述
  对比matlab均衡化后的直方图:
在这里插入图片描述
  matlab均衡化后的灰度直方图数据为:0、0、1、2、6、8、11、19、24、33、42、51、59、69
  Verilog均衡化后的灰度直方图数据为:0、0、2、3、7、9、12、19、24、34、43、51、60、69
  可以看出我们均衡化后的灰度直方图和matlab均衡化后的灰度直方图有一些细微的差异,这些都是精度带来的差距,可以忽略不计,总体的数据是一致的。

  仿真中,我们将均衡化后的图像生成在本文件夹里,命名为:new_gray_img.bmp,跑完仿真打开文件夹:

在这里插入图片描述
在这里插入图片描述
  我们可以看到均衡化后的图片,我们来对比一下matlab均衡化后的图片:

在这里插入图片描述

在这里插入图片描述
  我们可以看出用Verilog实现的直方图均衡化和matlab一致,我们用matlab统计我们Verilog均衡化后的图像的直方图以及累计直方图,matlab代码如下:

% 读取两幅灰度图像img1 = imread('...\....\.....\.....\gray_image_24bit.bmp'); 
img2 = imread('...\....\.....\.....\new_gray_img.bmp'); % 确保图像是灰度图像
if size(img1, 3) == 3img1 = rgb2gray(img1);
endif size(img2, 3) == 3img2 = rgb2gray(img2);
end% 计算直方图和累计直方图
[counts1, x1] = imhist(img1);
[counts2, x2] = imhist(img2);cumulativeHist1 = cumsum(counts1);
cumulativeHist2 = cumsum(counts2);% 创建一个新的图形窗口
figure;% 显示第一幅图像及其直方图和累计直方图
subplot(2, 3, 1);
imshow(img1);
title('第一幅灰度图像');subplot(2, 3, 2);
bar(x1, counts1, 'FaceColor', 'b');
title('第一幅图像的灰度直方图');
xlabel('灰度值');
ylabel('像素数量');subplot(2, 3, 3);
plot(x1, cumulativeHist1, 'r');
title('第一幅图像的累计直方图');
xlabel('灰度值');
ylabel('累计频数');% 显示第二幅图像及其直方图和累计直方图
subplot(2, 3, 4);
imshow(img2);
title('第二幅灰度图像');subplot(2, 3, 5);
bar(x2, counts2, 'FaceColor', 'g');
title('第二幅图像的灰度直方图');
xlabel('灰度值');
ylabel('像素数量');subplot(2, 3, 6);
plot(x2, cumulativeHist2, 'm');
title('第二幅图像的累计直方图');
xlabel('灰度值');
ylabel('累计频数');% 设置图形窗口的大小
set(gcf, 'Position', [100, 100, 800, 600]);

在这里插入图片描述

  至此,Verilog实现直方图均衡化已完成。

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

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

相关文章

嵌入式 开发技巧和经验分享

文章目录 前言嵌入式 开发技巧和经验分享目录1.1嵌入式 系统的 定义1.2 嵌入式 操作系统的介绍1.3 嵌入式 开发环境1.4 编译工具链和优化1.5 嵌入式系统软件开发1.6 嵌入式SDK开发2.1选择移植的系统-FreeRtos2.2FreeRtos 移植步骤2.3 系统移植之中断处理2.4系统移植之内存管理2…

【java面经】Redis速记

目录 基本概念 string hash list set zset 常见问题及解决 缓存穿透 缓存击穿 缓存雪崩 Redis内存管理策略 noeviction allkeys-lru allkeys-random volatile-random volatile-ttl Redis持久化机制 RDB快照 AOF追加文件 Redis多线程特性 Redis应用场景 缓…

【医学半监督】置信度指导遮蔽学习的半监督医学图像分割

摘要: 半监督学习(Semi-supervised learning)旨在利用少数标记数据和多数未标记数据训练出高性能模型。现有方法大多采用预测任务机制,在一致性或伪标签的约束下获得精确的分割图,但该机制通常无法克服确认偏差。针对这一问题,本文提出了一种用于半监督医学图像分割的新…

【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的?

【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的&#xff1f; 【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的&#xff1f; 文章目录 【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的&#xff1f;1. 什么是梯度&#xff1f;2.梯度…

2024-04-23 人工智能增强天基通信和传感

砺道智库2024-04-23 11:18 北京 据国家防务网4月19日报道&#xff0c;随着商业卫星、军事星座及其所有数据在太空中流动的数量不断增加&#xff0c;政府和行业运营商表示&#xff0c;他们正在寻求人工智能来帮助他们处理日益复杂的任务。 人工智能软件使用户能够在轨道上改变航…

饲料颗粒机全套设备有哪些机器组成

饲料颗粒机全套设备通常包括原料粉碎、混合机、制粒机、冷却器、筛分机、包装机以及配套的电气控制等多个部分组成&#xff1a;1、粉碎机&#xff1a;将各种饲料原料进行清理、去杂、破碎等预处理&#xff0c;确保原料的纯净度和适宜粒度&#xff0c;为后续加工做准备。2、混合…

【永磁同步电机(PMSM)】 5. PMSM 的仿真模型

【永磁同步电机&#xff08;PMSM&#xff09;】 5. PMSM 的仿真模型 1. 基于 Simulink 的仿真模型1.1 PMSM 的数学模型1.2 Simulink 仿真模型1.3 模块封装&#xff08;mask&#xff09;1.4 三相PMSM矢量控制仿真模型 2. Simscape 的 PMSM 模块2.1 PMSM 模块的配置2.2 PMSM 模块…

数据结构与算法学习day22-回溯算法-分割回文串、复原IP地址、子集

一、分割回文串 1.题目 131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 2.思路 分割回文串可以抽象为一棵树形结构。 递归用来纵向遍历&#xff0c;for循环用来横向遍历&#xff0c;切割线&#xff08;就是图中的红线&#xff09;切割到字符串的结尾位置&#xf…

WIFI路由器的套杆天线简谈

❝本次推文简单介绍下WIFI路由器的套杆天线。 路由器天线 路由器在这个万物互联的时代&#xff0c;想必大家对其都不陌生。随着科技的发展&#xff0c;常用的路由器上的天线也越来越多&#xff0c;那么问题来了&#xff1a;天线越多&#xff0c;信号越好吗&#xff1f;路由器…

浅谈Spring Cloud:认识微服务

SpringCloud就是分布式微服务架构的一站式解决方案&#xff0c;是微服务架构落地的多种技术的集合。 目录 微服务远程调用 Eureka注册中心 搭建Eureka Server 注册组件 服务拉取 当各种各样的服务越来越多&#xff0c;拆分的也越来越细&#xff0c;此时就会出现一个服务集…

计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

MySQL高阶1919-兴趣相同的朋友

题目 请写一段SQL查询获取到兴趣相同的朋友。用户 x 和 用户 y 是兴趣相同的朋友&#xff0c;需满足下述条件&#xff1a; 用户 x 和 y 是朋友&#xff0c;并且用户 x and y 在同一天内听过相同的歌曲&#xff0c;且数量大于等于三首. 结果表 无需排序 。注意&#xff1a;返…

常见排序(C语言版)

1.排序的概念及其应用 1.1排序的概念 排序&#xff1a;​ 在计算机科学与数学中&#xff0c;一个排序算法&#xff08;英语&#xff1a;Sorting algorithm&#xff09;是一种能将一串资料依照特定排序方式排列的算法。 稳定性&#xff1a;假定在待排序的记录序列中&#xff…

聚观早报 | 小米三折叠手机专利曝光;李斌谈合肥投资蔚来

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 9月20日消息 小米三折叠手机专利曝光 李斌谈合肥投资蔚来 索尼PS5 Pro包装亮相 新一代Spectacles AR眼镜发布 通…

《AI系统:原理与架构》于华为HC大会2024正式发布

2024年9月21日&#xff0c;《AI系统&#xff1a;原理与架构》新书发布会在上海世博馆华为HC大会顺利举办。本书由华为昇腾技术专家、B站AI科普博主ZOMI酱和哈工大软件学院副院长苏统华教授联合编写&#xff0c;是领域内AI系统方面填补空白的重磅之作。 发布会上&#xff0c;《A…

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中&#xff0c;都会进行自定义异常&#xff0c;并且都是需要配合统一结果返回进行使用。 1.背景引入 &#xff08;1&#xff09;背景介绍 为什么要处理异常&#xff1f;如果不处理项目中的异常信息&#xff0c;前端访问我们后端就是显示访问失败的…

JavaScript发送邮件:实现前端触发的教程?

JavaScript发送邮件的方式&#xff1f;怎么使用JavaScript发信&#xff1f; 无论是用户反馈、联系表单还是自动通知&#xff0c;前端触发的邮件发送功能都能极大地提升用户体验。AokSend将详细介绍如何通过JavaScript发送邮件&#xff0c;实现前端触发的邮件发送功能。 JavaS…

跨站请求伪造(CSRF)漏洞详解

免责申明 本文仅是用于学习检测自己搭建的DVWA靶场环境有关CSRF的原理和攻击实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法…

ubuntu24安装vivado24(安装并解决若干错误)

目录 安装方法&#xff1a;问题1&#xff1a;解决办法&#xff1a; 问题2&#xff1a;解决方法&#xff1a; 安装完成&#xff1a; 安装方法&#xff1a; 注意&#xff1a;内存最好预留80G空闲的。 安装好大小&#xff1a; 安装依赖库&#xff1a; sudo apt-get update sud…

计算机网络17——IM聊天系统——客户端核心处理类框架搭建

目的 拆开客户端和服务端&#xff0c;使用Qt实现客户端&#xff0c;VS实现服务端 Qt创建项目 Qt文件类型 .pro文件&#xff1a;配置文件&#xff0c;决定了哪些文件参与编译&#xff0c;怎样参与编译 .h .cpp .ui&#xff1a;画图文件 Qt编码方式 Qt使用utf-8作为编码方…