基于EBAZ4205矿板的图像处理:12图像二值化(阈值可调)

news2024/11/16 18:38:54

基于EBAZ4205矿板的图像处理:12图像二值化(阈值可调)

先看效果

板卡拿回寝室了,明天晚上再补充实际运行效果

我的项目是可以通过按键调整二值化的阈值的,key1为阈值加1,key2为阈值减1,key3为阈值加10,key4为阈值减10,key5为阈值重置为128。

项目解读

我的blockdesign,你不按照我的接,按照正点原子的开源代码接也是可以的,只是我有强迫症,能接的我都接了。
在这里插入图片描述
就是在标准的ov5640->VDMA->DDR->VDMA->DVI_Driver->HDMI的流程(可以点击这个超链接看我说的标准流程)的第一个箭头哪里加了三个模块,一个负责将图像从RGB格式转化为灰度图像,一个负责对灰度图像进行二值化处理,最后一个为PS提供了访问PL端reg的AXILite端口,以便实时调整阈值。

下面的代码里我都添加了(* X_INTERFACE_IGNORE = “true” *) ,是禁用vivado的interface自动推断,可以不加

rgb2gray模块

该模块负责将图像从RGB格式转化为灰度图像
公式:
Y = 0.299R +0.587G + 0.114B
Y = (77 R + 150G + 29 *B)>>8

`timescale 1ns / 1ps
//作者:抢公主的大魔王
//功能:将来自ov5640视频流从RGB格式转化为灰度图像
//日期:24.5.5
//版本:1v0
//联系方式:2376635586@qq.com
module rgb2gray(
    
(* X_INTERFACE_IGNORE = "true" *)  input           cmos_frame_vsync,
(* X_INTERFACE_IGNORE = "true" *)  input [23:0]    cmos_frame_data,
(* X_INTERFACE_IGNORE = "true" *)  input           cmos_frame_href,

(* X_INTERFACE_IGNORE = "true" *)  input           cmos_frame_clk,
(* X_INTERFACE_IGNORE = "true" *)  input           cmos_rstn,//同步复位
(* X_INTERFACE_IGNORE = "true" *)  input           cmos_frame_ce,

(* X_INTERFACE_IGNORE = "true" *)  output          dataout_frame_vsync,
(* X_INTERFACE_IGNORE = "true" *)  output [23:0]   dataout_frame_data,
(* X_INTERFACE_IGNORE = "true" *)  output          dataout_frame_href,
(* X_INTERFACE_IGNORE = "true" *)  output          dataout_frame_ce
    );
    // Y = 0.299R +0.587G + 0.114B
    // Y = (77 *R + 150*G + 29 *B)>>8
    reg [15:0] r_gray1;
    reg [15:0] g_gray1;
    reg [15:0] b_gray1;
    reg [15:0] y1;
    reg [7:0] y2;
    reg [2:0] dataout_frame_vsync_r;
    reg [2:0] dataout_frame_href_r;
    reg [2:0] dataout_frame_ce_r;


    always@(posedge cmos_frame_clk)begin
        if(!cmos_rstn)begin
            r_gray1 <= 8'h00;
            g_gray1 <= 8'h00;
            b_gray1 <= 8'h00;
        end
        else begin
            r_gray1 <= cmos_frame_data[23:16]  * 8'd77 ;
            g_gray1 <= cmos_frame_data[15:8]   * 8'd150;
            b_gray1 <= cmos_frame_data[7:0]    * 8'd29 ;
        end
    end

    always@(posedge cmos_frame_clk)begin
        if(!cmos_rstn)begin
            y1 <= 16'h0000;
        end
        else begin
            y1 <= r_gray1 + g_gray1 + b_gray1;
        end
    end

    always@(posedge cmos_frame_clk)begin
        if(!cmos_rstn)begin
            y2 <= 8'h0000;
        end
        else begin
            y2 <= y1[15:8];
        end
    end

    

    always@(posedge cmos_frame_clk)begin
        if(!cmos_rstn)begin
            dataout_frame_ce_r      <= 3'b000;
            dataout_frame_vsync_r   <= 3'b000;
            dataout_frame_href_r    <= 3'b000;
        end
        else begin
            dataout_frame_ce_r      <= {dataout_frame_ce_r[1:0]     ,cmos_frame_ce};
            dataout_frame_vsync_r   <= {dataout_frame_vsync_r[1:0]  ,cmos_frame_vsync};
            dataout_frame_href_r    <= {dataout_frame_href_r[1:0]   ,cmos_frame_href};
        end
    end
    assign dataout_frame_data = {y2,y2,y2};
    assign dataout_frame_ce = dataout_frame_ce_r[2];
    assign dataout_frame_vsync = dataout_frame_vsync_r[2];
    assign dataout_frame_href = dataout_frame_href_r[2];


endmodule

global_binary模块

负责根据阈值对灰度图像进行二值化处理

`timescale 1ns / 1ps
//作者:抢公主的大魔王
//功能:根据阈值对灰度图像进行二值化处理
//日期:24.5.5
//版本:1v0
//联系方式:2376635586@qq.com
module global_binary(
(* X_INTERFACE_IGNORE = "true" *)  input           datain_vsync,
(* X_INTERFACE_IGNORE = "true" *)  input [23:0]    datain,
(* X_INTERFACE_IGNORE = "true" *)  input           datain_href,

(* X_INTERFACE_IGNORE = "true" *)  input           datain_clk,
(* X_INTERFACE_IGNORE = "true" *)  input           datain_rstn,//同步复位
(* X_INTERFACE_IGNORE = "true" *)  input           datain_frame_ce,

(* X_INTERFACE_IGNORE = "true" *)  input      [7:0]threshold,

(* X_INTERFACE_IGNORE = "true" *)  output          dataout_vsync,
(* X_INTERFACE_IGNORE = "true" *)  output reg [23:0]   dataout,
(* X_INTERFACE_IGNORE = "true" *)  output          dataout_vaild,

(* X_INTERFACE_IGNORE = "true" *)  output          dataout_frame_ce
    );

reg [1:0] dataout_vsync_r;
reg [1:0] dataout_valid_r;
reg [1:0] dataout_frame_ce_r;
always@(posedge datain_clk)begin
    if(!datain_rstn)
        dataout <= 24'hff_ff_ff;
    else if(datain[7:0]>=threshold)
        dataout <= 24'hff_ff_ff;
    else
        dataout  <= 24'h00_00_00;
end
always@(posedge datain_clk)begin
    if(!datain_rstn) begin
        dataout_vsync_r     <=  3'b000;
        dataout_valid_r     <=  3'b000;
        dataout_frame_ce_r  <=  3'b000;
    end
    else begin
        dataout_vsync_r     <=  {dataout_vsync_r[0]     , datain_vsync};
        dataout_valid_r     <=  {dataout_valid_r[0]     , datain_href};
        dataout_frame_ce_r  <=  {dataout_frame_ce_r[0]  , datain_frame_ce};
    end
end

assign dataout_vsync        = dataout_vsync_r[1];
assign dataout_vaild        = dataout_valid_r[1];
assign dataout_frame_ce     = dataout_frame_ce_r[1];

endmodule

AXICtrlThreshold模块

在这里插入图片描述
这个就是自己打包的标准的AXILite IP核,然后加了两句代码,一句是将threshold的0到7为连接到这个IP内部的第一个reg的低八位,另一句就是让这个reg复位是被复位为128,而不是0,因为我的图像阈值二值化算法的缺省阈值为128。
打包过程如下
在这里插入图片描述
在这里插入图片描述
下面要改名字和描述哦。
在这里插入图片描述
在这里插入图片描述
然后到了这个AXILite IP内部添加下面的代码

assign threshold = slv_reg0[7:0];

然后更改复位值

	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      slv_reg0 <= 32'd128;
	      slv_reg1 <= 0;
	      slv_reg2 <= 0;
	      slv_reg3 <= 0;
	    end 

最后把它output出去

output wire [7:0] threshold

IP代码本身,和她的top层都要output
在这里插入图片描述

然后在这一栏,所有不是对号的要挨个点一遍,挨个更新一下,最后全是对号之后,就可以打包了。
在这里插入图片描述

vitis端代码

IntrHandler是中断回调函数,触发中断后会调用这个函数。
SetupInterruptSystem负责初始化中断,配置触发中断方式,使能中断。
Gpio_Init初始化GPIO,包括key1-5,led1-3和sccb总线(配置OV5640的)
binary_threshold就是我的图像阈值二值化的阈值啦,可以通过按键进行调整。

//作者:抢公主的大魔王
//功能:阈值可调的图像二值化
//日期:24.5.5
//版本:1v0
//联系方式:2376635586@qq.com

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xil_types.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xplatform_info.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"
#include "display_ctrl_hdmi/display_ctrl.h"
#include "vdma_api/vdma_api.h"
#include "emio_sccb_cfg/emio_sccb_cfg.h"
#include "ov5640/ov5640_init.h"
#include "sleep.h"

//宏定义
#define DYNCLK_BASEADDR  	XPAR_AXI_DYNCLK_0_BASEADDR  //动态时钟基地址
#define VDMA_ID          	XPAR_AXIVDMA_0_DEVICE_ID    //VDMA器件ID
#define DISP_VTC_ID      	XPAR_VTC_0_DEVICE_ID        //VTC器件ID
#define THRESHOLD_BASEADDR 	XPAR_AXICTRLTHRESHOLD_0_S00_AXI_BASEADDR

#define EMIO_SCL_NUM 54
#define EMIO_SDA_NUM 55
#define KEY1 56 //T19
#define KEY2 57 //P19
#define KEY3 58 //U20
#define KEY4 59 //U19
#define KEY5 60 //V20
#define LED1 61 //H18
#define LED2 62 //K17
#define LED3 63 //E19

#define GPIO_DEVICE_ID  	XPAR_XGPIOPS_0_DEVICE_ID
XGpioPs Gpio;
#define GPIO_BANK	XGPIOPS_BANK0  /* Bank 0 of the GPIO Device */
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define GPIO_INTERRUPT_ID	XPAR_XGPIOPS_0_INTR

//全局变量
//frame buffer的起始地址
unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR
										+ 0x1000000);
u8 binary_threshold = 128;
XAxiVdma     vdma;
DisplayCtrl  dispCtrl;
VideoMode    vd_mode;

static XScuGic Intc; /* The Instance of the Interrupt Controller Driver */


static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
	XGpioPs *Gpio_cb = (XGpioPs *)CallBackRef;
	if (XGpioPs_IntrGetStatusPin(Gpio_cb, KEY1)){
		binary_threshold++;
		Xil_Out32(THRESHOLD_BASEADDR, binary_threshold);
		xil_printf("The threshold has been changed\n\r The threshold now is %d\n\r",binary_threshold);
	}
	else if (XGpioPs_IntrGetStatusPin(Gpio_cb, KEY2)){
		binary_threshold--;
		Xil_Out32(THRESHOLD_BASEADDR, binary_threshold);
		xil_printf("The threshold has been changed\n\r The threshold now is %d\n\r",binary_threshold);
	}
	else if (XGpioPs_IntrGetStatusPin(Gpio_cb, KEY3)){
		binary_threshold = binary_threshold+10;
		Xil_Out32(THRESHOLD_BASEADDR, binary_threshold);
		xil_printf("The threshold has been changed\n\r The threshold now is %d\n\r",binary_threshold);
	}
	else if (XGpioPs_IntrGetStatusPin(Gpio_cb, KEY4)){
		binary_threshold = binary_threshold-10;
		Xil_Out32(THRESHOLD_BASEADDR, binary_threshold);
		xil_printf("The threshold has been changed\n\r The threshold now is %d\n\r",binary_threshold);
	}
	else if (XGpioPs_IntrGetStatusPin(Gpio_cb, KEY5)){
		binary_threshold = 128;
		Xil_Out32(THRESHOLD_BASEADDR, binary_threshold);
		xil_printf("The threshold has been reset\n\r The threshold now is %d\n\r",binary_threshold);
	}
	XGpioPs_WritePin(&Gpio, LED1, !XGpioPs_ReadPin(&Gpio, LED1));
}



void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
				u16 GpioIntrId){

	XScuGic_Config *IntcConfig;
	Xil_ExceptionInit();

	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);

	XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
				GicInstancePtr);
	XScuGic_Connect(GicInstancePtr, GpioIntrId,
				(Xil_ExceptionHandler)IntrHandler,
				(void *)Gpio);


	XScuGic_Enable(GicInstancePtr, GpioIntrId);

	XGpioPs_SetIntrTypePin(Gpio, KEY1,  XGPIOPS_IRQ_TYPE_EDGE_FALLING);
	XGpioPs_SetIntrTypePin(Gpio, KEY2,  XGPIOPS_IRQ_TYPE_EDGE_FALLING);
	XGpioPs_SetIntrTypePin(Gpio, KEY3,  XGPIOPS_IRQ_TYPE_EDGE_FALLING);
	XGpioPs_SetIntrTypePin(Gpio, KEY4,  XGPIOPS_IRQ_TYPE_EDGE_FALLING);
	XGpioPs_SetIntrTypePin(Gpio, KEY5,  XGPIOPS_IRQ_TYPE_EDGE_FALLING);

	XGpioPs_IntrEnablePin(Gpio, KEY1);
	XGpioPs_IntrEnablePin(Gpio, KEY2);
	XGpioPs_IntrEnablePin(Gpio, KEY3);
	XGpioPs_IntrEnablePin(Gpio, KEY4);
	XGpioPs_IntrEnablePin(Gpio, KEY5);

	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
}


void Gpio_Init(void){
	XGpioPs_Config *ConfigPtr;

	ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);

	XGpioPs_SetDirectionPin(&Gpio, LED1, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, LED1, 1);
	XGpioPs_WritePin(&Gpio, LED1, 0);

	XGpioPs_SetDirectionPin(&Gpio, LED2, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, LED2, 1);
	XGpioPs_WritePin(&Gpio, LED2, 0);

	XGpioPs_SetDirectionPin(&Gpio, LED3, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, LED3, 1);
	XGpioPs_WritePin(&Gpio, LED3, 0);

	XGpioPs_SetDirectionPin(&Gpio, KEY1, 0);
	XGpioPs_SetDirectionPin(&Gpio, KEY2, 0);
	XGpioPs_SetDirectionPin(&Gpio, KEY3, 0);
	XGpioPs_SetDirectionPin(&Gpio, KEY4, 0);
	XGpioPs_SetDirectionPin(&Gpio, KEY5, 0);

	//设置 sccb端口 为输出
	XGpioPs_SetDirectionPin(&Gpio, EMIO_SCL_NUM, 1);
	XGpioPs_SetDirectionPin(&Gpio, EMIO_SDA_NUM, 1);

	//使能sccb端口 输出
	XGpioPs_SetOutputEnablePin(&Gpio, EMIO_SCL_NUM, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, EMIO_SDA_NUM, 1);

	//将sccb的SCLK和SDA都拉高
	XGpioPs_WritePin(&Gpio, EMIO_SCL_NUM, 1);
	XGpioPs_WritePin(&Gpio, EMIO_SDA_NUM, 1);

	SetupInterruptSystem(&Intc, &Gpio, GPIO_INTERRUPT_ID);
}


int main(void)
{
	u32 status;
	u16 cmos_h_pixel;                    //ov5640 DVP 输出水平像素点数
	u16 cmos_v_pixel;                    //ov5640 DVP 输出垂直像素点数
	u16 total_h_pixel;                   //ov5640 水平总像素大小
	u16 total_v_pixel;                   //ov5640 垂直总像素大小

	cmos_h_pixel = 1280;
	cmos_v_pixel = 720;
	total_h_pixel = 2570;
	total_v_pixel = 980;


	Gpio_Init();                         //初始化EMIO
	status = ov5640_init( cmos_h_pixel,  //初始化ov5640
						  cmos_v_pixel,
						 total_h_pixel,
						 total_v_pixel);//设置OV5640输出分辨率为1280*720  PCLK = 72Mhz
	if(status == 0)
		xil_printf("OV5640 detected successful!\r\n");
	else
		xil_printf("OV5640 detected failed!\r\n");

	vd_mode = VMODE_1280x720;

	//配置VDMA
	run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,
							frame_buffer_addr,0,0,BOTH);
    //初始化Display controller
	DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR);
    //设置VideoMode
	DisplaySetMode(&dispCtrl, &vd_mode);
	DisplayStart(&dispCtrl);

	while(1){
		XGpioPs_WritePin(&Gpio, LED3, !XGpioPs_ReadPin(&Gpio, LED3));
		sleep(1);
	}
    return 0;
}


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

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

相关文章

vue初始化项目

打开终端输入vue create project-name 选择Manually select features回车&#xff0c;继续选择如下&#xff1a; 如果要使用pina就可以不选vuex&#xff0c;回车&#xff0c;选择如下&#xff1a; 按下图选即可

SX1301 1MHz、2A升压电流模式PWM转换器芯片IC

一般说明 S1301是直流-直流之间的a电流。安装Wμ电路内置0.25Ω功率MOSFET&#xff0c;使此稳压器高功率效率。内部补偿网络还可最大限度地减少多达6个外部元件数量。误差放大器的同相输入端接0.6V精密基准电压&#xff0c;内部具有软启动功能&#xff0c;可以减小浪涌电…

Hikyuu-SYS-趋势双均线交易策略实现

本篇中&#xff0c;我们将通过技术分析流派中经典的“趋势双均线策略”&#xff0c;向大家展现如何 Hikyuu 来测试自己的想法&#xff0c;并最终将它转化为策略&#xff01; 准备工作 下面的代码在 Jupyter Lab 中执行&#xff0c;和直接使用 .py 文件执行的区别主要在于 matp…

C语言--带环链表问题

继续学习 一、判断链表是否带环 141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;用快慢指针&#xff0c;快指针走两步&#xff0c;慢指针走一步&#xff0c;当慢指针走一半快指针进到环里 当慢指针进环&#xff0c;快指针已经在环中转了一会儿了 | |…

【论文笔记】Training language models to follow instructions with human feedback B部分

Training language models to follow instructions with human feedback B 部分 回顾一下第一代 GPT-1 &#xff1a; 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式&#xff1b;模型架构是基于 Transformer 的叠加解码器&#xff08;掩码自注意…

C语言二叉树代码实现

声明&#xff1a;著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 采用二叉链表作为存储结构&#xff0c;完成二叉树的建立&#xff0c;先序、中序和后序遍历的操作&#xff0c;求所有叶子及结点总数的操作等。 #include <stdio.h> #i…

ctfshow 框架复现

文章目录 web 466web 467web 468web469web 470web 471web 472web 473web 474web 475web 476 web 466 Laravel5.4版本 &#xff0c;提交数据需要base64编码 代码审计学习—Laravel5.4 - 先知社区 (aliyun.com) 用第二条链子 反序列化格式 /admin/序列化串base64<?php na…

牛客NC383 主持人调度(一)【简单 排序 Java/Go/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/e160b104354649b69600803184094adb 思路 直接看代码&#xff0c;不难Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返…

用python画一个正八边形

1 问题 使用turtle库的turtle.fd()函数和turtle.seth()函数绘制一个边长100的正八边形。 2 方法 1、利用for循环解决如何画出图形中相同的八条边的问题。 2、再利用turtle.fd()函数和turtle.seth()函数画出完整的图形。 代码清单 1 import turtleturtle.pensize(2)d0for i in r…

第77天:WAF 攻防-权限控制代码免杀异或运算变量覆盖混淆加密传参

目录 案例一&#xff1a; 代码-脚本后门免杀变异-覆盖&传参 传参 变量覆盖 案例二&#xff1a;代码-脚本后门免杀变异-异或&加密 加密 异或 案例三&#xff1a;免杀脚本生成代码 php免杀脚本 案例一&#xff1a; 代码-脚本后门免杀变异-覆盖&传参 传参 正…

【C++程序员的自我修炼】string 库中常见用法(二)

制芰荷以为衣兮 集芙蓉以为裳 不吾知其亦已兮 苟余情其信芳 目录 字符串的头部插入insert <1>头部插入一个字符串&#xff1a; <2>头部插入一个字符&#xff1a; <3>迭代器的插入 总结&#xff1a; 字符串的头部删除 erase <1>头部插入删除一个字符&a…

Spring入门及注解开发

1 引言 自定义注解可以用来为代码添加元数据信息,简化配置,提高代码的可读性和可维护性。通过自定义注解,可以实现自定义的业务逻辑、约束条件、配置参数等功能。在Spring中,自定义注解常用于标记组件、配置依赖注入、AOP切面等。 自定义注解可以添加元数据信息,低代码框…

使用sherpa-onnx给文字添加标点符号

上篇文章https://blog.csdn.net/AWNUXCVBN/article/details/138372795 识别出的文字都是没有标点符号的&#xff0c;虽然可以添加整句断行&#xff0c;但总觉得怪怪的…… 于是看了一下&#xff0c;ncnn没有添加标点符号的功能&#xff0c;翻了一下onnx有示例&#xff0c;但没有…

【测试报告】网页聊天室

⭐ 作者&#xff1a;Jwenen &#x1f331; 作者主页&#xff1a;Jwenen的个人主页 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 测试报告 1. 编写目的2. 项目介绍3. 功能测试用例4. 自动化测试源码 1. 编写目的 本报告为网页聊…

【华为】AC直连二层组网隧道转发实验配置

【华为】AC直连二层组网隧道转发实验配置 实验需求拓扑配置AC数据规划表 AC的配置顺序AC1基本配置(二层通信)AP上线VAP组关联--WLAN业务流量 LSW1AR1STA获取AP的业务流量 配置文档 实验需求 AC组网方式&#xff1a;直连二层组网。 业务数据转发方式&#xff1a;隧道转发。 DHC…

Odoo14修改登录界面,实现炫酷粒子效果

目录 原登录界面 最终效果 实现步骤 插件下载 原登录界面 最终效果 实现步骤 1 odoo创建插件web_login 2 在static目录下编写css和js文件 login.css代码 html, body {position:fixed;top:0px;left:0px;height:100%;width:100%;/*Fallback if gradeints dont work */b…

ASP.NET网上车辆档案管理系统

摘 要 本文采用基于Web的Asp.net技术&#xff0c;并与sql server 2000数据库相结合&#xff0c;研发了一套车辆档案管理系统。该系统扩展性好&#xff0c;易于维护。简化了车辆档案设计流程&#xff0c;去除了冗余信息。汽车销售企业可以通过本系统完成整个销售及售后所有档案…

python数据分析——数据分析概念定义和发展前景

数据分析概念定义和发展前景 前言一、数据分析概念二、数据的定义2.1数据的定义2.2数据的分类 三、数据的价值数据为什么具有价值 四、数据分析的目的对于企业来说 五、数据分析类型的划分5.1描述性统计分析5.2 探索性数据分析5.3 传统的统计分析方法5.4验证性数据分析 六、 数…

[答疑]系统需求并不会修改领域事实(警惕伪创新)

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 jeri 2024-4-17 12:59 潘老师&#xff0c;在整理领域模型时&#xff0c;这个申请是有多次的&#xff0c;直到申请成功&#xff0c;多重性是* &#xff0c;但分析模型时&#xff0c;需…

【题解】NowCoder Fibonacci数列

题目来源&#xff1a;牛客 题目链接&#xff1a;Fibonacci数列 Fibonacci数列 题目描述&#xff1a; Fibonacci 数列是这样定义的&#xff1a; F[0] 0 F[1] 1 for each i ≥ 2 : F[i] F[i-1] F[i-2] 因此&#xff0c;Fibonacci 数列就形如&#xff1a;0, 1, 1, 2, 3, 5…