ISP算法之坏点校正DPC(二):Verilog硬件实现与仿真

DPC的算法讲解和MATLAB仿真参考上一节:

ISP算法之坏点校正DPC(一):MATLAB仿真验证-CSDN博客

本节讲解Verilog的硬件实现与仿真

行缓存设计

DPC算法是基于窗口邻域的像素级别算法,因此需要对实时到来的视频流进行行缓存,行缓存的设计参考:Verilog实现图像处理的行缓存Line Buffer_verilog行缓冲-CSDN博客

行缓存会并行输出N行同一列位置的数据,在算法模块实例化行缓存模块并对其并行输出打拍寄存就可以得到一定大小的窗口数据。

Pipeline设计

硬件设计的难点是拆分算法逻辑并对齐时序,将算法实现的步骤按照Pipeline的方式进行分解,在每个时钟周期完成一个步骤并寄存,经过一定延时后,每个时钟周期完成处理并输出一个像素。

例如在下列pipeline框图中,一个实现被差分成了3个时钟周期ABC,每个时钟周期实现一部分组合逻辑(A、B、C),延时一段时间后(3个时钟周期),每个时钟周期都能处理完ABC三个过程,这样的设计其实是面积换速度策略,通过添加寄存器存储中间值来实现Pipeline。

 DPC硬件设计框架

按照Pipeline的设计方式,DPC的数据流与算法硬件pipeline设计框架图如下所示:

每个时钟周期的已经用T1~T10表示。

1、通过行缓存得到并行的四行相同列的数据,同时输入第5行数据,此过程需要对行缓存和输入的像素进行打拍得到窗口大小的像素区域。

2、得到5x5窗口区域后,根据当前Bayer像素的格式R/B或G得到邻域区域的9个像素点(包含中心像素),详细查看上一节中的MATLAB仿真验证。

3、接下来充分利用硬件的并行性,同时进行中值的求取和坏点的检测过程,最后根据是否是坏点来输出中值或原值。每个过程按照Pipeline拆分为子过程。

计算中值

这里中值的获取采用三分法的原理,可以参考:

3x3开窗中值滤波器的FPGA硬件实现 - olivermahout - 博客园

(该方法的证明可以参考网络上的博客,这里会使用即可)

通过此方法无需对9个像素进行复杂的排序操作,只需要三三比较即可。

坏点检测

由于坏点检测当中涉及到了减法,因此需要对参与计算的数据扩展一位位宽用于符号判断(0正1负),如上述算法框图中过程6。计算得到的差值通过最高位来判断正负。

如果全为正或全为负且差值的绝对值超过一定阈值则判断为坏点,绝对值的计算使用有符号的0减去为负的数值。详细查看代码中的注释

t4_diff1 <= t3_diff1[BITS] ? 1'sd0 - t3_diff1 : t3_diff1; 

对齐控制时序

随数据输入的还有HREF和VSYNC控制信号,需要对这些信号进行时序对齐,由于算法整个算法Pipeline过程延时为10个时钟周期,所以对这些信号也统一打拍10个时钟周期。

verilog硬件设计源码

`timescale 1 ns / 1 ns

/*
 * ISP - Defective Pixel Correction
 */

/*
 * bayer 5x5邻域内同意颜色通道相对于中心像素都有8个临近像素。矫正按以下步骤操作:
 * 计算中心像素与周围八个像素值的差;
 * 判断八个差值是否都为正值或者都为负值;
 * 如果有的为正有的为负,那么就为正常值,否则进行下一步;
 * 设置一个阈值,如果八个差值的绝对值都查过阈值,那么就判断为坏点;
 * 判断为坏点后就用八个临近的像素值的中位值来替换当前的像素值;
*/

module isp_dpc
#(
	parameter BITS = 8,
	parameter WIDTH = 1280,
	parameter HEIGHT = 960,
	parameter BAYER = 0      //0:RGGB 1:GRBG 2:GBRG 3:BGGR
)
(
	input pclk,
	input rst_n,

	input [BITS-1:0] threshold,    //阈值越小,检测越松,坏点检测数越多

	input in_href,
	input in_vsync,
	input [BITS-1:0] in_raw,

	output out_href,
	output out_vsync,
	output [BITS-1:0] out_raw
);

	wire [BITS-1:0] shiftout;
	wire [BITS-1:0] tap3x, tap2x, tap1x, tap0x;


	shift_register #(BITS, WIDTH, 4) linebuffer(pclk, in_href, in_raw, shiftout, {tap3x, tap2x, tap1x, tap0x});   //缓存4行,第5行开始实时处理
	
	reg [BITS-1:0] in_raw_r;                 
	reg [BITS-1:0] p11,p12,p13,p14,p15;         5x5窗口
	reg [BITS-1:0] p21,p22,p23,p24,p25;
	reg [BITS-1:0] p31,p32,p33,p34,p35;
	reg [BITS-1:0] p41,p42,p43,p44,p45;
	reg [BITS-1:0] p51,p52,p53,p54,p55;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			in_raw_r <= 0;
			p11 <= 0; p12 <= 0; p13 <= 0; p14 <= 0; p15 <= 0;
			p21 <= 0; p22 <= 0; p23 <= 0; p24 <= 0; p25 <= 0;
			p31 <= 0; p32 <= 0; p33 <= 0; p34 <= 0; p35 <= 0;
			p41 <= 0; p42 <= 0; p43 <= 0; p44 <= 0; p45 <= 0;
			p51 <= 0; p52 <= 0; p53 <= 0; p54 <= 0; p55 <= 0;
		end
		else begin
			in_raw_r <= in_raw;
			p11 <= p12; p12 <= p13; p13 <= p14; p14 <= p15; p15 <= tap3x;
			p21 <= p22; p22 <= p23; p23 <= p24; p24 <= p25; p25 <= tap2x;
			p31 <= p32; p32 <= p33; p33 <= p34; p34 <= p35; p35 <= tap1x;
			p41 <= p42; p42 <= p43; p43 <= p44; p44 <= p45; p45 <= tap0x;
			p51 <= p52; p52 <= p53; p53 <= p54; p54 <= p55; p55 <= in_raw_r;
		end
	end

	reg odd_pix;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n)
			odd_pix <= 0;
		else if (!in_href)    
			odd_pix <= 0;
		else
			odd_pix <= ~odd_pix;      //对列进行奇偶判断
	end
	wire odd_pix_sync_shift = odd_pix;
	
	reg prev_href;   //数据有效信号寄存一拍,用于后续提取下降沿
	always @ (posedge pclk or negedge rst_n) begin 
		if (!rst_n) 
			prev_href <= 0;
		else
			prev_href <= in_href;
	end	
	
	reg odd_line;
	always @ (posedge pclk or negedge rst_n) begin //对行进行奇偶判断
		if (!rst_n) 
			odd_line <= 0;
		else if (in_vsync)
			odd_line <= 0;
		else if (prev_href & (~in_href))     //数据有效下降沿
			odd_line <= ~odd_line;
		else
			odd_line <= odd_line;
	end
	wire odd_line_sync_shift = odd_line;

    //根据输入的图像格式和奇偶行判断窗口中心像素的格式
	wire [1:0] p33_fmt = BAYER[1:0] ^ {odd_line_sync_shift, odd_pix_sync_shift};    //pixel format 0:[R]GGB 1:R[G]GB 2:RG[G]B 3:RG



	reg [BITS-1:0] t1_p1, t1_p2, t1_p3;                   //3x3窗口  
	reg [BITS-1:0] t1_p4, t1_p5, t1_p6;
	reg [BITS-1:0] t1_p7, t1_p8, t1_p9;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t1_p1 <= 0; t1_p2 <= 0; t1_p3 <= 0;
			t1_p4 <= 0; t1_p5 <= 0; t1_p6 <= 0;
			t1_p7 <= 0; t1_p8 <= 0; t1_p9 <= 0;
		end
		else begin
			case (p33_fmt)    //根据中间像素的格式分离出不同的模式
				2'd0,2'd3: begin //R/B ,在5x5窗口中,中心点红色和绿色像素可以提取3x3
					t1_p1 <= p11; t1_p2 <= p13; t1_p3 <= p15;     
					t1_p4 <= p31; t1_p5 <= p33; t1_p6 <= p35;
					t1_p7 <= p51; t1_p8 <= p53; t1_p9 <= p55;
				end
				2'd1,2'd2: begin //Gr/Gb   //同样提取9个绿色像素
					t1_p1 <= p22; t1_p2 <= p13; t1_p3 <= p24;
					t1_p4 <= p31; t1_p5 <= p33; t1_p6 <= p35;
					t1_p7 <= p42; t1_p8 <= p53; t1_p9 <= p44;
				end
				default: begin
					t1_p1 <= 0; t1_p2 <= 0; t1_p3 <= 0;
					t1_p4 <= 0; t1_p5 <= 0; t1_p6 <= 0;
					t1_p7 <= 0; t1_p8 <= 0; t1_p9 <= 0;
				end
			endcase
		end
	end

	//中值滤波 step1  
	reg [BITS-1:0] t2_min1, t2_med1, t2_max1;
	reg [BITS-1:0] t2_min2, t2_med2, t2_max2;
	reg [BITS-1:0] t2_min3, t2_med3, t2_max3;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t2_min1 <= 0; t2_med1 <= 0; t2_max1 <= 0;
			t2_min2 <= 0; t2_med2 <= 0; t2_max2 <= 0;
			t2_min3 <= 0; t2_med3 <= 0; t2_max3 <= 0;
		end
		else begin
			t2_min1 <= min(t1_p1, t1_p2, t1_p3);
			t2_med1 <= med(t1_p1, t1_p2, t1_p3);
			t2_max1 <= max(t1_p1, t1_p2, t1_p3);
			t2_min2 <= min(t1_p4, t1_p5, t1_p6);
			t2_med2 <= med(t1_p4, t1_p5, t1_p6);
			t2_max2 <= max(t1_p4, t1_p5, t1_p6);
			t2_min3 <= min(t1_p7, t1_p8, t1_p9);
			t2_med3 <= med(t1_p7, t1_p8, t1_p9);
			t2_max3 <= max(t1_p7, t1_p8, t1_p9);
		end
	end

	//中值滤波 step2  
	reg [BITS-1:0] t3_max_of_min, t3_med_of_med, t3_min_of_max;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t3_max_of_min <= 0; t3_med_of_med <= 0; t3_min_of_max <= 0;
		end
		else begin
			t3_max_of_min <= max(t2_min1, t2_min2, t2_min3);
			t3_med_of_med <= med(t2_med1, t2_med2, t2_med3);
			t3_min_of_max <= min(t2_max1, t2_max2, t2_max3);
		end
	end

	//中值滤波 step3  
	reg [BITS-1:0] t4_medium;      //该中值就是3x3窗口的中值
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t4_medium <= 0;
		end
		else begin
			t4_medium <= med(t3_max_of_min, t3_med_of_med, t3_min_of_max);
		end
	end

	//将中值打拍对齐到坏点检测时序
	reg [BITS-1:0] t5_medium;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t5_medium <= 0;
		end
		else begin
			t5_medium <= t4_medium;
		end
	end

	//坏点检测 step1 (转有符号数)
	reg signed [BITS:0] t2_p1, t2_p2, t2_p3;         //扩展一位用于符号计算
	reg signed [BITS:0] t2_p4, t2_p5, t2_p6;
	reg signed [BITS:0] t2_p7, t2_p8, t2_p9;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t2_p1 <= 0; t2_p2 <= 0; t2_p3 <= 0;
			t2_p4 <= 0; t2_p5 <= 0; t2_p6 <= 0;
			t2_p7 <= 0; t2_p8 <= 0; t2_p9 <= 0;
		end
		else begin
			t2_p1 <= {1'b0,t1_p1}; t2_p2 <= {1'b0,t1_p2}; t2_p3 <= {1'b0,t1_p3};
			t2_p4 <= {1'b0,t1_p4}; t2_p5 <= {1'b0,t1_p5}; t2_p6 <= {1'b0,t1_p6};
			t2_p7 <= {1'b0,t1_p7}; t2_p8 <= {1'b0,t1_p8}; t2_p9 <= {1'b0,t1_p9};
		end
	end

	//坏点检测 step2 (计算中心像素与周围八个像素值的差)
	reg [BITS:0] t3_center;
	reg signed [BITS:0] t3_diff1, t3_diff2, t3_diff3, t3_diff4, t3_diff5, t3_diff6, t3_diff7, t3_diff8;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t3_center <= 0;
			t3_diff1 <= 0; t3_diff2 <= 0;
			t3_diff3 <= 0; t3_diff4 <= 0;
			t3_diff5 <= 0; t3_diff6 <= 0;
			t3_diff7 <= 0; t3_diff8 <= 0;
		end
		else begin
			t3_center <= t2_p5[BITS-1:0];     //求取差值,得出的是补码
			t3_diff1 <= t2_p5 - t2_p1;
			t3_diff2 <= t2_p5 - t2_p2;
			t3_diff3 <= t2_p5 - t2_p3;
			t3_diff4 <= t2_p5 - t2_p4;
			t3_diff5 <= t2_p5 - t2_p6;
			t3_diff6 <= t2_p5 - t2_p7;
			t3_diff7 <= t2_p5 - t2_p8;
			t3_diff8 <= t2_p5 - t2_p9;
		end
	end

	//坏点检测 step3 (判断差值是否都为正或都为负,计算差值绝对值)
	reg t4_defective_pix;
	reg [BITS-1:0] t4_center;
	reg [BITS-1:0] t4_diff1, t4_diff2, t4_diff3, t4_diff4, t4_diff5, t4_diff6, t4_diff7, t4_diff8;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t4_defective_pix <= 0;
			t4_center <= 0;
			t4_diff1 <= 0; t4_diff2 <= 0;
			t4_diff3 <= 0; t4_diff4 <= 0;
			t4_diff5 <= 0; t4_diff6 <= 0;
			t4_diff7 <= 0; t4_diff8 <= 0;
		end
		else begin
			t4_center <= t3_center;    //判断最高位是否都为正或者都为负,最高位0为正,1为负
			t4_defective_pix <= (8'b0000_0000 == {t3_diff1[BITS],t3_diff2[BITS],t3_diff3[BITS],t3_diff4[BITS],t3_diff5[BITS],t3_diff6[BITS],t3_diff7[BITS],t3_diff8[BITS]})
							 || (8'b1111_1111 == {t3_diff1[BITS],t3_diff2[BITS],t3_diff3[BITS],t3_diff4[BITS],t3_diff5[BITS],t3_diff6[BITS],t3_diff7[BITS],t3_diff8[BITS]});
			t4_diff1 <= t3_diff1[BITS] ? 1'sd0 - t3_diff1 : t3_diff1;    //有符号数减法相当于取绝对值
			t4_diff2 <= t3_diff2[BITS] ? 1'sd0 - t3_diff2 : t3_diff2;
			t4_diff3 <= t3_diff3[BITS] ? 1'sd0 - t3_diff3 : t3_diff3;
			t4_diff4 <= t3_diff4[BITS] ? 1'sd0 - t3_diff4 : t3_diff4;
			t4_diff5 <= t3_diff5[BITS] ? 1'sd0 - t3_diff5 : t3_diff5;
			t4_diff6 <= t3_diff6[BITS] ? 1'sd0 - t3_diff6 : t3_diff6;
			t4_diff7 <= t3_diff7[BITS] ? 1'sd0 - t3_diff7 : t3_diff7;
			t4_diff8 <= t3_diff8[BITS] ? 1'sd0 - t3_diff8 : t3_diff8;
		end
	end

	//坏点检测 step4 (判断差值绝对值是否超出阈值)
	reg t5_defective_pix;
	reg [BITS-1:0] t5_center;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t5_defective_pix <= 0;
			t5_center <= 0;
		end
		else begin
			t5_center <= t4_center;   //如果与邻域差值都为正或者负,且差值绝对值达到阈值,则认为该点为坏点
			t5_defective_pix <= t4_defective_pix && t4_diff1 > threshold && t4_diff2 > threshold && t4_diff3 > threshold && t4_diff4 > threshold && 
													t4_diff5 > threshold && t4_diff6 > threshold && t4_diff7 > threshold && t4_diff8 > threshold;
		end
	end

	//坏点检测 step5 (坏点成立输出中值滤波值, 非坏点输出原值)
	reg [BITS-1:0] t6_center;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			t6_center <= 0;
		end
		else begin
			t6_center <= t5_defective_pix ? t5_medium : t5_center;   //如果是坏点则输出中值滤波值,否则输出原值
		end
	end

	localparam DLY_CLK = 10;          //对控制信号进行打拍以对齐时序
	reg [DLY_CLK-1:0] href_dly;
	reg [DLY_CLK-1:0] vsync_dly;
	always @ (posedge pclk or negedge rst_n) begin
		if (!rst_n) begin
			href_dly <= 0;
			vsync_dly <= 0;
		end
		else begin
			href_dly <= {href_dly[DLY_CLK-2:0], in_href};
			vsync_dly <= {vsync_dly[DLY_CLK-2:0], in_vsync};
		end
	end
	
    //输出对齐后的控制时序
	assign out_href = href_dly[DLY_CLK-1];
	assign out_vsync = vsync_dly[DLY_CLK-1];
	assign out_raw = out_href ? t6_center : {BITS{1'b0}};

	function [BITS-1:0] min;      //求三个值中的最小值
		input [BITS-1:0] a, b, c;
		begin
			min = (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
		end
	endfunction
	function [BITS-1:0] med;   //取三个值中的中值
		input [BITS-1:0] a, b, c;
		begin
			med = (a < b) ? ((b < c) ? b : (a < c ? c : a)) : ((b > c) ? b : (a > c ? c : a));
		end
	endfunction
	function [BITS-1:0] max;   //求三个值中的最大值
		input [BITS-1:0] a, b, c;
		begin
			max = (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
		end
	endfunction
endmodule

Verilog仿真验证

(验证框架的搭建查看往期博客)

编写testbench,实例化算法模块,代码如下:

`timescale 1ns / 1ns

module tb_dpc;

reg xclk = 0;
always #5 xclk <= ~xclk;     //像素时钟
 
reg rst_n = 0;               //axis 时钟复位 
initial begin
    rst_n <= 0;
    #100 rst_n <= 1;
end


localparam BAYER = 3;
localparam BITS     = 10;      
localparam WIDTH    = 2592;
localparam HEIGHT   = 1944;
localparam IN_FILE  = "E:/ISP/tb_dpc_2592x1944_16.raw";
localparam OUT_FILE = "E:/ISP/tb_dpc_2592x1944_16_verilogout.raw";
 

reg [BITS-1:0] dpc_thresh=100;    ///DPC阈值参数


FILE TO DVP/
wire pclk_in, href_in, vsyn_in,hsync_in;
wire [BITS-1:0] data_in;

FILE_TO_DVP #(
    .FILE(IN_FILE),
    .BITS(BITS),
    .H_DISP(WIDTH),
    .V_DISP(HEIGHT)
)
file_to_dvp_inst
(
    .xclk(xclk),
    .rst_n(rst_n),
    .pclk(pclk_in),
    .href(href_in),
    .hsync(hsync_in),
    .vsync(vsyn_in),
    .data(data_in)
);
 
ISP算法
wire [BITS-1:0] data_o;
wire href_o,vsyn_o;


isp_dpc #(
    .BITS(BITS),
    .WIDTH(WIDTH),
    .HEIGHT(HEIGHT),
    .BAYER(BAYER)
) dpc_inst(
    .pclk(pclk_in),
    .rst_n(rst_n),
    .threshold(dpc_thresh),
    .in_href(href_in),
    .in_vsync(vsyn_in),
    .in_raw(data_in),
    .out_href(href_o),
    .out_vsync(vsyn_o),
    .out_raw(data_o)
);
//


///DVP to FILE
DVP_TO_FILE #(
    .FILE(OUT_FILE),
    .BITS(BITS)
)
dvp_to_file_inst
(
    .pclk(pclk_in),
    .rst_n(rst_n),
    .href(href_o),
    .vsync(vsyn_o),
    .data(data_o)
);
   
endmodule

输入raw图像为:

(测试图像的生成参考往期博客)

得到的raw仅进行demosaic后得到如下:

 可以看到坏点基本被消除,与MATAB仿真得到的结果基本一致。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

clearvoice 语音降噪、语音分离库

参看: https://github.com/modelscope/ClearerVoice-Studio/tree/main ClearVoice 提供了一个统一的推理平台,用于语音增强、语音分离以及视听目标说话人提取。 代码参看: https://github.com/modelscope/ClearerVoice-Studio/tree/main/clearvoice https://github.com/mode…

Linux(网络协议和管理)

后面也会持续更新&#xff0c;学到新东西会在其中补充。 建议按顺序食用&#xff0c;欢迎批评或者交流&#xff01; 缺什么东西欢迎评论&#xff01;我都会及时修改的&#xff01; 在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频 王晓春老师的个人空间…

代理 IP 行业现状与未来趋势分析

随着互联网的飞速发展&#xff0c;代理 IP 行业在近年来逐渐兴起并成为网络技术领域中一个备受关注的细分行业。它在数据采集、网络营销、隐私保护等多个方面发挥着重要作用&#xff0c;其行业现状与未来发展趋势值得深入探讨。 目前&#xff0c;代理 IP 行业呈现出以下几个显著…

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成&#xff1f;安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯&#xff0c;并且它确实相对其他的 IDE 较为轻量化…

【热力学与工程流体力学】流体静力学实验,雷诺实验,沿程阻力实验,丘里流量计流量系数测定,局部阻力系数的测定,稳态平板法测定材料的导热系数λ

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

基于单片机的无绳跳绳设计

基于单片机设计了一款无绳跳绳&#xff0c;采用传感器代替了绳子的摆动&#xff0c;从而实现了模拟跳绳的功能。其研究的方法是&#xff1a;以单片机作为这次设计的核心&#xff0c;它的外围包含有传感器模块、按键模块、显示模块、语音播报模块及电源模块等。本设计采用STM32芯…

暂停一下,给Next.js项目配置一下ESLint(Next+tailwind项目)

前提 之前开自己的GitHub项目&#xff0c;想着不是团队项目&#xff0c;偷懒没有配置eslint&#xff0c;后面发现还是不行。eslint的存在可以帮助我们规范代码格式&#xff0c;同时 ctrl s保存立即调整代码格式是真的很爽。 除此之外&#xff0c;团队使用eslint也是好处颇多…

音频进阶学习八——傅里叶变换的介绍

文章目录 前言一、傅里叶变换1.傅里叶变换的发展2.常见的傅里叶变换3.频域 二、欧拉公式1.实数、虚数、复数2.对虚数和复数的理解3.复平面4.复数和三角函数5.复数的运算6.欧拉公式 三、积分运算1.定积分2.不定积分3.基本的积分公式4.积分规则线性替换法分部积分法 5.定积分计算…

Mac m2电脑上安装单机Hadoop(伪集群)

1. 引言 本教程旨在介绍在Mac 电脑上安装Hadoop 2. 前提条件 2.1 安装JDK Mac电脑上安装Hadoop&#xff0c;必须首先安装JDK&#xff0c;并配置环境变量&#xff08;此处不做详细描述&#xff09; 2.2 配置ssh环境 关闭防火墙 在Mac下配置ssh环境&#xff0c;防止后面启…

【记录49】vue2 vue-office在线预览 docx、pdf、excel文档

vue2 在线预览 docx、pdf、excel文档 docx npm install vue-office/docx vue-demi0.14.6 指定版本 npm install vue-office/docx vue-demi <template><VueOfficeDocx :src"pdf" style"height: 100vh;" rendere"rendereHandler" error&…

「LangChain4j入门 — JavaAI程序」

█ 什么是大模型&#xff1f; 大模型&#xff0c;英文名叫 Large Model&#xff0c;大型模型。早期的时候&#xff0c;也叫 Foundation Model&#xff0c;基础模型。 大模型是一个简称。完整的叫法&#xff0c;应该是 “人工智能预训练大模型”。预训练&#xff0c;是一项技术…

【SQL】语句练习

1. 更新 1.1单表更新 例1: 所有薪水低于30000的员工薪水增加10% SQL命令&#xff1a; update employee set salarysalary*1.1 where salary < 30000; 1.2多表更新 例1: 将下图两表张三的语文成绩从95修改为80 SQL命令&#xff1a; update exam set score80 where subjec…

蓝桥杯刷题——day6

蓝桥杯刷题——day6 题目一题干解题思路代码 题目二题干解题思路代码 题目一 题干 小明发现49很有趣&#xff0c;首先&#xff0c;它是个平方数。它可以拆分为4和9&#xff0c;拆分出来的部分也是平方数。169 也有这个性质&#xff0c;我们权且称它们为&#xff1a;拼接平方数…

SQL中的联结表

本文介绍什么是联结&#xff0c;为什么使用联结&#xff0c;以及如何编写使用联结的SELECT语句。 1. 联结 SQL最强大的功能之一就是能在数据查询的执行中联结&#xff08;join&#xff09;表。联结是SQL的SELECT能执行的最重要的操作&#xff0c;理解联结及其语法是学习SQL的…

.Net WebAPI(一)

文章目录 项目地址一、WebAPI基础1. 项目初始化1.1 创建简单的API1.1.1 get请求1.1.2 post请求1.1.3 put请求1.1.4 Delete请求 1.2 webapi的流程 2.Controllers2.1 创建一个shirts的Controller 3. Routing3.1 使用和创建MapControllers3.2 使用Routing的模板语言 4. Mould Bind…

SQL在线格式化 - 加菲工具

SQL在线格式化 打开网站 加菲工具 选择“SQL 在线格式化” 或者直接访问 https://www.orcc.online/tools/sql 输入sql&#xff0c;点击上方的格式化按钮即可 输入框得到格式化后的sql结果

vs 调试

常用&#xff1a; 调试->窗口-> 断点 监视 自动窗口 局部变量 调用堆栈 内存 反汇编&#xff08;也可以右键&#xff0c;转到反汇编&#xff09; 寄存器 快捷键&#xff1a; F5:启用调试&#xff0c;经常用来跳到下一个断点处 F9创建断点和取消断点。断点的重要作用&…

25. 深浅拷贝

一、什么是浅拷贝 只对对象的最顶层进行的拷贝称为 浅拷贝。我们可以用 copy 模块中的 copy() 方法实现浅拷贝。 import copya [11, 22, 33] b [44, 55, 66] c [a, b] d copy.copy(c)print(f"c: {c}") print(f"d: {d}") print(f"c d: {c d}&q…

docker简单命令

docker images 查看镜像文件 docker ps -a 查看容器文件 docker rm 0b2 删除容器文件&#xff0c;id取前三位即可 docker rmi e64 删除镜像文件&#xff08;先删容器才能删镜像&#xff09;&#xff0c;id取前三位即可 在包含Dockerfile文件的目录…

【Java】4、虚拟机 JVM

目录 Java内存区域详解(重点) JVM垃圾回收详解(重点) 类文件结构详解 类加载过程详解 类加载器详解(重点) 最重要的JVM参数总结 JDK监控和故障处理工具总结 JVM线上问题排查和性能调优案例 参考&#xff1a; JVM 核心技术 32 讲 深入浅出 Java 虚拟机