fpga学习——zynq图像处理中的DVP流接口封装

fpga学习——zynq图像处理中的DVP流接口封装之前文章介绍了基于zynq的图像处理架构问题。其中,作为开发者,需要重点关注图像传感器接口、处理算法、显示接口,这些模块。现在我们一同学习用于视频数据接口的DVP模块,并将其封装成AXI-stream接口便于直接和VDMAIP通信。DVP_AXIstreamIPv1.0使用说明1.设计概述•用于cmos传感器视频数据采集,将cmos输出的8位视频数据拼接成RGB565模式•AXI_stream主机接口,用于和PS端内存的数据交互•基于vivado18.3软件设计2.模块分析

大家好,又见面了,我是你们的朋友全栈君。

之前文章介绍了基于zynq的图像处理架构问题。其中,作为开发者,需要重点关注图像传感器接口、处理算法、显示接口,这些模块。现在我们一同学习用于视频数据接口的DVP模块,并将其封装成AXI-stream接口便于直接和VDMA IP通信。

DVP_AXI stream IP v1.0使用说明

1.设计概述

•用于cmos传感器视频数据采集,将cmos输出的8位视频数据拼接成RGB 565模式

•AXI_stream主机接口,用于和PS端内存的数据交互
•基于vivado 18.3软件设计

2.模块分析

此设计包括DVP模块及AXI_stream 协议部分。DVP模块负责将采集的8位视频数据及行、场同步信号按照相应时序转换成16位RGB模式输出,DVP模块独立封装,在顶层模块中调用。AXI_stream 部分用于产生相应的AXI_stream接口信号,设计采用AXI_stream主机模式。模块框架图如下图所示。

fpga学习——zynq图像处理中的DVP流接口封装

图1.DVP_AXI stream IP 核模块框架图

DVP模块:

DVP模块是实现视频数据采集的主要部分。

等到初始化摄像完成且行场同步信号出现,释放清零信号,开始写入数据;利用采样计数器对采样数据计数,计数值在行同步信号有效时加1,否则清零;见以下代码。

//在HREF为高电平时,计数输出数据个数

//565模式下的计数器

always@(posedge PCLK or posedge Rst_p)

if(Rst_p)

Hcount_1 <= 0;

else if(r_Href)

Hcount_1 <= Hcount_1 + 1’d1;

else

Hcount_1 <= 0;

cmos输出采样的数据是8位的,需要将其转换成16位的RGB565数据模式输出。根据采样计数器的计数值奇偶情况输出数据,在计数值为偶数时,将采样的8位数据存到待输出像素数据的高字节,在计数值为奇数时,将数据存到输出像素数据的低字节。见以下代码。

begin 

   if(!Hcount_1[0])

r_DataPixel[15:8] <= r_Data;

   else 

r_DataPixel[7:0] <= r_Data;

end

在此数据拼接过程中,相当于每两个时钟像素完成了一次数据输出,需要指定输出数据有效的标志,以避免错误的数据输出。在将两个单字节采样数据拼接成一个两个字节数据的过程中,第一个时刻的采样数据给到输出数据的高字节,第二个时刻的采样数据给到输出数据的低字节,并且采样计数器从0开始计数,因此指定当采样计数器为奇数时数据有效。见以下代码。

begin 

if(Hcount_1[0] && r_Href)

              r_DataValid <= 1;

      else

              r_DataValid <= 0;

end

为保证传图的稳定性,传感器开始工作时舍弃前10帧,见以下代码。

/*帧计数器,对每次系统开始运行后的前10帧图像进行计数*/

  always@(posedge PCLK or posedge Rst_p)

  if(Rst_p)  

    FrameCnt <= 0;

  else if({
r_Vsync,Vsync}== 2’b01)begin

    if(FrameCnt >= 10)

      FrameCnt <= 4’d10;

    else

      FrameCnt <= FrameCnt + 1’d1;

    end

  else

    FrameCnt <= FrameCnt;

  /*舍弃每次系统开始运行后的前10帧图像的数据,以确保输出图像稳定*/

  always@(posedge PCLK or posedge Rst_p)

  if(Rst_p)

    dump_frame <= 0;

  else if(FrameCnt >= 10)

    dump_frame <= 1’d1;

  else

dump_frame <= 0;

AXI_stream 接口部分:

   此部分主要作用是产生AXI_stream 接口相关的信号。

   根据AXI_stream时序,主机和从机之间需要建立握手信号以传输数据。利用主机的数据有效标志信号(m_axis_video_tvaild)以及从机的响应信号(m_axis_video_tready)实现握手协议。

   m_axis_video_tlast在AXI_stream中为传输的一个数据包的的边缘,在这里可给定为一行的结束,可由对行同步信号的边沿检测确定;m_axis_video_tuser为用户自定义的数据包边界信号,这里给定为一帧的开始,可由对帧同步信号的边沿检测得到。

   由于DVP模块由cmos产生的像素时钟产驱动,而AXI_stream接口的数据传输由系统时钟驱动,在模块中添加异步fifo保证信号的同步性。使用这个fifo有两个目的:

  1. 处理跨时钟域问题。

    2.为视频数据输入和AXI_stream 流数据输出的缓冲。

结合数据的有效信号、从机的响应信号来确定异步fifo的读写使能。

xpm_fifo_async_inst (

      .rst              (~cmos_aresetn),

      .wr_clk           (cmos_pclk),

      .wr_en            (s_axis_tvalid & fifo_ready),

      .din              ({
s_axis_tdata,s_axis_tlast,s_axis_tuser}),

      .full             (full),

      .overflow         (),

      .prog_full        (),

      .wr_data_count    (),

      .almost_full      (),

      .wr_ack           (),

      .wr_rst_busy      (),

      .rd_clk           (m_axis_video_aclk),

      .rd_en            (m_axis_video_tready & ~empty & fifo_ready_maxis),

      .dout          ({
m_axis_video_tdata,m_axis_video_tlast,m_axis_video_tuser}),

      .empty            (empty),

      .underflow        (),

      .rd_rst_busy      (),

      .prog_empty       (),

      .rd_data_count    (),

      .almost_empty     (),

      .data_valid       (),

      .sleep            (1’b0),

      .injectsbiterr    (1’b0),

      .injectdbiterr    (1’b0),

      .sbiterr          (),

      .dbiterr          ()

)

3.端口说明

fpga学习——zynq图像处理中的DVP流接口封装

 图2.DVP_AXI stream IP 核端口示意图

fpga学习——zynq图像处理中的DVP流接口封装

注:在实际使用时,cmos传感器根据设置输出相应的的采样时钟,如1280*720p时为84Mhz。

4.功能仿真

编写TestBench文件,模拟cmos采样信号的输入,观察输出波形,分析功能是否达到要求。

首先生成时钟,总共两路时钟,一路是的输入的采样时钟,这里用50MHz代替,一路是AXI_stream接口的驱动时钟,这里用100Mhz代替。此外,产生行、场同步信号的同时利用循环产生像素数据。这里简化了“一帧”的像素数量,简化为每帧12行,每行16个数据,循环出15帧TestBench 主要内容如下:

//产生时钟

  initial cmos_pclk = 1;

  always # 10 cmos_pclk = ~cmos_pclk;//cmos像素时钟设置为50M,实际使用时84M等

  initial m_axis_video_aclk = 1;

  always # 5 m_axis_video_aclk = ~m_axis_video_aclk;//AXIS接口驱动时钟设置为100M,实际使用时150M等

//产生行、场同步信号和视频数据,这里简化了“一帧”的像素数量,简化为每帧12行,每行16个数据,循环出15帧

parameter WIDTH = 16;

    parameter HIGHT = 12;

    integer i,j;

    initial begin

    m_axis_video_aresetn = 0;  

    m_axis_video_tready=0; 

    cmos_vsync=0;

    cmos_href=0;

    cmos_d=8’hff;

    #200;

    m_axis_video_aresetn = 1; 

    m_axis_video_tready=1; 

    #200;

    repeat(15)begin

      cmos_vsync = 1;

      #100;

      cmos_vsync = 0;

      #200;

      for(i=0;i<HIGHT;i=i+1)

      begin

        for(j=0;j<WIDTH;j=j+1)

      begin

          cmos_href=1;

          cmos_d=cmos_d1;

          #20;

       end

        cmos_href=0;

        #100;

       end

       end

        $stop;

       end

endmodule

fpga学习——zynq图像处理中的DVP流接口封装

图3.DVP_AXI stream 模块功能仿真波形图 

5.使用说明

此设计输出的是RGB 565模式,AXI_stream主机接口用于与PS端的数据交互,通过vivado自带的VDMA IP进行视频流数据的内存读写。此外,实际应用时,用于HDMI接口的显示模块输入的是RGB888模式的24位数据,可在此IP后接入vivado自带的视频流位宽转换IP——AXI4_Stream_Subset_Converter,将RGB565转换为RGB888模式输出。端口连接如下图所示。

fpga学习——zynq图像处理中的DVP流接口封装

 图4.DVP_AXI stream IP与AXI4_Stream_Subset_Converter IP的连接

有需要工程的朋友可以联系我,感谢各位同学,欢迎指正,一块学习进步!

源代码如下:

1.top


`timescale 1ns / 1ps
module userIP_ov5640
#(
   parameter BUFFER_DEPTH = 4096
)
(
    input                                        cmos_vsync,       //cmos vsync
    input                                        cmos_href,        //cmos hsync refrence
    input                                        cmos_pclk,        //cmos pxiel clock
    input   [9:0]                                cmos_d,           //cmos data

    // AXI4-Stream signals
    input                                        m_axis_video_aclk,     // AXI4-Stream clock
    input                                        m_axis_video_aresetn,  // AXI4-Stream reset, active low
    output [15:0]                                m_axis_video_tdata,    // AXI4-Stream data
    output                                       m_axis_video_tvalid,   // AXI4-Stream valid
    input                                        m_axis_video_tready,   // AXI4-Stream ready
    output                                       m_axis_video_tuser,    // AXI4-Stream tuser (SOF)
    output                                       m_axis_video_tlast,    // AXI4-Stream tlast (EOL)
    output[1:0]                                  m_axis_video_tkeep     // AXI4-Stream tkeep
    
    );
assign        m_axis_video_tkeep = 2'b11;
wire[15:0]    cmos_d_16bit;
wire          cmos_href_16bit;
reg[7:0]      cmos_d_d0;
reg           cmos_href_d0;
reg           cmos_vsync_d0;
reg           cmos_vsync_d1;
wire          cmos_hblank;
reg           s_axis_tlast;
reg           s_axis_tuser;
wire          s_axis_tready;
reg           cmos_hblank_d0;
reg           cmos_hblank_d1;
reg           cmos_href_16bit_d0;
reg           cmos_href_16bit_d1;
reg[15:0]     cmos_d_16bit_d0;
reg[15:0]     cmos_d_16bit_d1;
wire          s_axis_tvalid = cmos_href_16bit_d1 & cmos_hblank_d1 & s_axis_tready;   //dvp输出有效数据到axis接口的标志信号
wire[15:0]    s_axis_tdata = cmos_d_16bit_d1;                                       //dvp输出的数据连接到axis接口
reg[31:0]     reset_cnt;
reg[31:0]     fifo_ready_cnt;
reg           fifo_ready;
reg           cmos_aresetn;
//reg           axis_reset;
reg           fifo_ready_maxis;
 
 //信号同步
always@(posedge m_axis_video_aclk)
begin
   // axis_reset <= cmos_aresetn;
    fifo_ready_maxis <= fifo_ready;
end

//产生DVP复位信号
always@(posedge cmos_pclk)
begin
    if(reset_cnt < 32'd200_000_000)   //延时复位,可改变大小
    begin
        reset_cnt <= reset_cnt + 32'd1;
        cmos_aresetn <= 1'b0;
    end
    else
    begin
        cmos_aresetn <= 1'b1;
    end
end

always@(posedge cmos_pclk)
begin
    if(cmos_aresetn == 1'b0)
    begin
        fifo_ready_cnt <= 32'd0;
        fifo_ready <= 1'b0;
    end
    else if(fifo_ready_cnt < 32'd100_000_000)
    begin
        fifo_ready_cnt <= fifo_ready_cnt + 32'd1;
        fifo_ready <= 1'b0;
    end
    else
    begin
        fifo_ready <= 1'b1;
    end
end

always@(posedge cmos_pclk)
begin
    if(cmos_aresetn == 1'b0)
    begin
        cmos_d_d0 <= 8'd0;
        cmos_href_d0 <= 1'b0;
        cmos_vsync_d0 <= 1'b0;
        cmos_vsync_d1 <= 1'b0;
    end
    else
    begin
        cmos_d_d0 <= cmos_d[9:2];
        cmos_href_d0 <= cmos_href;
        cmos_vsync_d0 <= cmos_vsync;
        cmos_vsync_d1 <= cmos_vsync_d0;
    end    
end
//例化DVP模块
DVP DVP0
(
  . Rst_p(~cmos_aresetn),                        
  . PCLK(cmos_pclk),                  //像素时钟
  . Vsync(cmos_vsync_d0),             //帧同步
  . Href(cmos_href_d0),               //行刷新
  . Data(cmos_d_d0),                  //采样数据         

  .ImageState(),                     //采样状态
  .DataValid(cmos_href_16bit),       //数据有效标志
  .DataPixel(cmos_d_16bit),          //并行数据输出
  .DataHs(cmos_hblank),              //行同步信号输出          
  .DataVs(),                         //帧同步信号输出
  .Xaddr(),                          //行方向数据采样地址
  .Yaddr()                           //列方向数据采样地址
);
always@(posedge cmos_pclk)
begin
    if(cmos_aresetn == 1'b0)
    begin
        cmos_hblank_d0 <= 1'b0;
        cmos_hblank_d1 <= 1'b0;
        cmos_d_16bit_d0 <= 1'b0;
        cmos_d_16bit_d1 <= 1'b0;
        cmos_href_16bit_d0 <= 1'b0;
        cmos_href_16bit_d1 <= 1'b0;
        s_axis_tlast <= 1'b0;
    end
    else
    begin
        cmos_hblank_d0 <= cmos_hblank;
        cmos_hblank_d1 <= cmos_hblank_d0;
        cmos_d_16bit_d0 <= cmos_d_16bit;
        cmos_d_16bit_d1 <= cmos_d_16bit_d0;
        cmos_href_16bit_d0 <= cmos_href_16bit;
        cmos_href_16bit_d1 <= cmos_href_16bit_d0;
        s_axis_tlast <= cmos_hblank_d0 & ~cmos_hblank;  //s_axis_tlast一行的开始
    end    
end

always@(posedge cmos_pclk)
begin
    if(cmos_aresetn == 1'b0)
        s_axis_tuser <= 1'b0;
    else if(cmos_vsync_d1 == 1'b1 && cmos_vsync_d0 == 1'b0) //标志着一帧的最开始的数据
        s_axis_tuser <= 1'b1;
    else if(s_axis_tuser == 1'b1 && s_axis_tvalid == 1'b1) //数据有效后s_axis_tuser 置零,s_axis_tuser 只保持几个周期的高电平
        s_axis_tuser <= 1'b0;
end


wire empty;
wire full;
assign m_axis_video_tvalid = ~empty & m_axis_video_tready;
assign s_axis_tready = ~full;

//使用原语进行异步fifo例化
//使用这个fifo有两个目的:处理跨时钟域问题作为视频数据输入和AXI_stream 流数据输出的缓冲
xpm_fifo_async # (

  .FIFO_MEMORY_TYPE          ("auto"),           //string; "auto", "block", or "distributed";
  .ECC_MODE                  ("no_ecc"),         //string; "no_ecc" or "en_ecc";
  .RELATED_CLOCKS            (0),                //positive integer; 0 or 1
  .FIFO_WRITE_DEPTH          (BUFFER_DEPTH),     //positive integer
  .WRITE_DATA_WIDTH          (18),               //positive integer
  .WR_DATA_COUNT_WIDTH       (12),               //positive integer
  .PROG_FULL_THRESH          (10),               //positive integer
  .FULL_RESET_VALUE          (0),                //positive integer; 0 or 1
  .USE_ADV_FEATURES          ("0707"),           //string; "0000" to "1F1F";
  .READ_MODE                 ("fwft"),            //string; "std" or "fwft";
  .FIFO_READ_LATENCY         (0),                //positive integer;
  .READ_DATA_WIDTH           (18),               //positive integer
  .RD_DATA_COUNT_WIDTH       (12),               //positive integer
  .PROG_EMPTY_THRESH         (10),               //positive integer
  .DOUT_RESET_VALUE          ("0"),              //string
  .CDC_SYNC_STAGES           (2),                //positive integer
  .WAKEUP_TIME               (0)                 //positive integer; 0 or 2;

) xpm_fifo_async_inst (

      .rst              (~cmos_aresetn),
      .wr_clk           (cmos_pclk),
      .wr_en            (s_axis_tvalid & fifo_ready),
      .din              ({s_axis_tdata,s_axis_tlast,s_axis_tuser}),
      .full             (full),
      .overflow         (),
      .prog_full        (),
      .wr_data_count    (),
      .almost_full      (),
      .wr_ack           (),
      .wr_rst_busy      (),
      .rd_clk           (m_axis_video_aclk),
      .rd_en            (m_axis_video_tready & ~empty & fifo_ready_maxis),
      .dout             ({m_axis_video_tdata,m_axis_video_tlast,m_axis_video_tuser}),
      .empty            (empty),
      .underflow        (),
      .rd_rst_busy      (),
      .prog_empty       (),
      .rd_data_count    (),
      .almost_empty     (),
      .data_valid       (),
      .sleep            (1'b0),
      .injectsbiterr    (1'b0),
      .injectdbiterr    (1'b0),
      .sbiterr          (),
      .dbiterr          ()

);
endmodule

 

`timescale 1ns / 1ps

///coms数据采集模块
///

module DVP#(
          parameter coms_mode=16
)
(
  input Rst_p,                        
  input PCLK,                          //像素时钟
  input Vsync,                         //帧同步
  input Href,                          //行刷新
  input [7:0] Data,                    //采样数据         

  output reg ImageState,                     //采样状态
  output DataValid,                          //数据有效标志
  output [coms_mode-1:0] DataPixel,          //并行数据输出
  output DataHs,                             //行同步信号输出          
  output DataVs,                             //帧同步信号输出
  output [11:0] Xaddr,                       //行方向数据采样地址
  output [11:0] Yaddr                        //列方向数据采样地址
);

//内部寄存器
  reg r_Vsync;
  reg r_Href;
  reg [7:0] r_Data;

  reg [coms_mode-1:0]r_DataPixel;
  reg r_DataValid;
  reg r_DataHs;    
  reg r_DataVs;
  reg [12:0]Hcount_1;                        //565模式下的采样数据计数器
  reg [11:0]Vcount;                          //使用Vcount计数器对HREF信号的高电平进行计数,统计一帧图像中的每一行图像的行号
  reg [3:0] FrameCnt;                        //帧计数器,前10帧舍弃
  reg [12:0]Hcount_2;                        //888模式下的采样数据计数器
  reg [12:0]Xaddr_cnt;                       //行方向数据采样地址计数器
  reg dump_frame;                            //帧计数器计满10帧的标志

  //等到初始化摄像完成且头场同步信号出现,释放清零信号,开始写入数据
  always@(posedge PCLK or posedge Rst_p)
  if (Rst_p)  
    ImageState <= 1'b1;
  else if(r_Vsync)
    ImageState <= 1'b0;

  //对DVP接口的数据使用寄存器打一拍,以用信号边沿检测功能
  always@(posedge PCLK)
  begin
    r_Vsync <= Vsync;
    r_Href  <= Href;
    r_Data  <= Data;
  end

  //在HREF为高电平时,计数输出数据个数
  //565模式下的计数器
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)
    Hcount_1 <= 0;
  else if(r_Href)
    Hcount_1 <= Hcount_1 + 1'd1;
  else
    Hcount_1 <= 0;
	
   //888模式下的计数器
    always@(posedge PCLK or posedge Rst_p)
    if(Rst_p)
      Hcount_2 <= 0;
    else if(r_Href)begin
      if (Hcount_2==2)
      Hcount_2<=0;
      else
      Hcount_2 <= Hcount_2 + 1'd1;
      end  
    else
      Hcount_2 <= 0;

  /*565模式下:根据计数器的计数值奇数和偶数的区别,在计数器为偶数时,
  将DVP接口数据端口上的数据存到输出像素数据的高字节,在计
  数器为奇数时,将DVP接口数据端口上的数据存到输出像素数据
  的低字节*/
  //888模式下,根据计数器的值控制r/g/b的数据,计数器位0时数据给datapixel的高位.....
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)
      r_DataPixel <= 0;
  else if ((coms_mode==24)&&r_Href)begin 
      if (Hcount_2==0)
			r_DataPixel[23:16] <= r_Data;
	  else if (Hcount_2==1)
			r_DataPixel[15:8] <= r_Data;
	  else if (Hcount_2==2)
			r_DataPixel[7:0] <= r_Data;
	  end
  else begin 
	   if(!Hcount_1[0])
			r_DataPixel[15:8] <= r_Data;
	   else 
			r_DataPixel[7:0] <= r_Data;
	    end

  /*rgb565在行计数器计数值为奇数,且HREF高电平期间,产生输出;
  rgb888模式,计数到2有效数据有效信号*/
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)
         r_DataValid <= 0;
   else if ((coms_mode==24))begin
         if ((Hcount_2==2)&&r_Href)
           r_DataValid <= 1;
         else
           r_DataValid <= 0;
         end
     else 
       begin if(Hcount_1[0] && r_Href)
              r_DataValid <= 1;
               else
                 r_DataValid <= 0;
        end
    
  always@(posedge PCLK)
  begin
    r_DataHs <= r_Href;
    r_DataVs <= ~r_Vsync;
  end

  /*使用Vcount计数器对HREF信号的高电平进行计数,统计
  一帧图像中的每一行图像的行号*/
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)
    Vcount <= 0;
  else if(r_Vsync)
    Vcount <= 0;
  else if({r_Href,Href} == 2'b01)
    Vcount <= Vcount + 1'd1;
  else
    Vcount <= Vcount;

  /*输出X地址*/  
  assign Yaddr = Vcount;

  /*对于RGB565模式,由于一行N个像素的图像输出2N个数据,所以Hcount_1计数值为N的2倍,将该计数值除以2后即可作为Xaddr输出;
  对于RGB88模式,由于一行N个像素的图像输出3N个数据,所以Xaddr可以通过对Hcount_2计数满2确定*/
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)
    Xaddr_cnt <= 0;
  else if(r_Href)begin
    if(Hcount_2==2)
       Xaddr_cnt <=Xaddr_cnt+1;
    else
          Xaddr_cnt <=Xaddr_cnt;
     end
   else 
         Xaddr_cnt <=0;
  assign Xaddr = (coms_mode==24)?Xaddr_cnt:Hcount_1[12:1];

  /*帧计数器,对每次系统开始运行后的前10帧图像进行计数*/
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)  
    FrameCnt <= 0;
  else if({r_Vsync,Vsync}== 2'b01)begin
    if(FrameCnt >= 10)
      FrameCnt <= 4'd10;
    else
      FrameCnt <= FrameCnt + 1'd1;
  end
  else
    FrameCnt <= FrameCnt;

  /*舍弃每次系统开始运行后的前10帧图像的数据,以确保输出图像稳定*/
  always@(posedge PCLK or posedge Rst_p)
  if(Rst_p)
    dump_frame <= 0;
  else if(FrameCnt >= 10)
    dump_frame <= 1'd1;
  else
    dump_frame <= 0;

  assign DataPixel = r_DataPixel;
  assign DataValid = r_DataValid & dump_frame;
  assign DataHs = r_DataHs & dump_frame;
  assign DataVs = r_DataVs & dump_frame;

endmodule

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138592.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • matlab验证确认和测试,验证和确认快速入门[通俗易懂]

    matlab验证确认和测试,验证和确认快速入门[通俗易懂]请选择其一AlabamaAlaska美属萨摩亚APO/FPOAAAPO/FPOAEAPO/FPOAPArizonaArkansasCaliforniaCarolineIslandsColoradoConnecticutDelawareDistrictofColumbiaFlorida格鲁吉亚关岛HawaiiIdahoIllinoisIndianaIowaKansasKentuckyLo…

  • pycharm所有文件中查找_python查找文件

    pycharm所有文件中查找_python查找文件PyCharm的FindinPath功能提供了全局查找功能,快捷键为Ctrl+Shift+F。Find则是在当前文件查找,快捷键为Ctrl+F。这两个个功能非常实用。FindinPath的使用:按快捷键Ctrl+Shift+F或从从菜单Edit-》Find-》FindinPath进入全局查找界面。如下图所示,在Texttofind输入要查找的内容,可以说某

  • SPSS实战:单因素方差分析(ANOVA)

    SPSS实战:单因素方差分析(ANOVA)SPSS:单因素方差分析方差分析单因素方差分析单因素方差分析的原理单因素方差分析的SPSS操作方差分析方差分析是一种假设检验,它把观测总变异的平方和与自由度分解为对应不同变异来源的平方和与自由度,将某种控制性因素所导致的系统性误差和其他随机性误差进行对比,从而推断各组样本之间是否存在显著性差异,以分析该因素是否对总体存在显著性影响。方差分析法采用离差平方和对变差进行度量,从总离差平方和分解出可追溯到指定来源的部分离差平方和。方差分析要求样本满足以下条件:可比性:资料中各组均数本身必须具有可比性,这是

  • html播放rtsp流,浏览器播放rtsp视频流解决方案

    html播放rtsp流,浏览器播放rtsp视频流解决方案最近项目中需要实时播放摄像头rtsp视频流,于是就专门做了些研究。而浏览器不能直接播放,只有通过插件或者转码来实现这个需求。要实现这个目的,可以采用的方案非常得多,有商业的也有开源的,这里主要列举一些开源的方案。这里的方案都是我尝试过了的,有些成功,有些没成功。但是因为每个项目情况不同,这次没成的方法,换个项目也许就能成。方案一:html5+websocket_rtsp_proxy实现视频…

    2022年10月17日
  • Java实现邮件发送

    Java实现邮件发送Java实现邮件发送一、邮件服务器与传输协议要在网络上实现邮件功能,必须要有专门的邮件服务器。这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。SMTP服务器地址:一般是smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。SMTP协议通常把处理用户smtp请求(邮件…

  • 用LoadRunner开发开心网外挂「建议收藏」

    用LoadRunner开发开心网外挂「建议收藏」现在基于WEB页面的网络游戏越来越流行,由于是基于HTTP的,因此应该可以用LoadRunner来开发外挂。今天略为试了一下,证实是可行的。以开心网的争车位游戏为例,用LoadRunner录制Web(HTTP/HTML)脚本,并进行适当的修改,主要是做一些关联和参数化。为速度起见,删掉一些资源请求的脚本。脚本摘录如下:Action(){char*parkID…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号