大创项目推荐 题目:基于机器视觉的图像矫正 (以车牌识别为例) - 图像畸变校正

文章目录

  • 0 简介
  • 1 思路简介
    • 1.1 车牌定位
    • 1.2 畸变校正
  • 2 代码实现
    • 2.1 车牌定位
      • 2.1.1 通过颜色特征选定可疑区域
      • 2.1.2 寻找车牌外围轮廓
      • 2.1.3 车牌区域定位
    • 2.2 畸变校正
      • 2.2.1 畸变后车牌顶点定位
      • 2.2.2 校正
  • 7 最后

0 简介

🔥 优质竞赛项目系列,今天要分享的是

基于机器视觉的图像矫正 (以车牌识别为例)

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 思路简介

目前车牌识别系统在各小区门口随处可见,识别效果貌似都还可以。查阅资料后,发现整个过程又可以细化为车牌定位、畸变校正、车牌分割和内容识别四部分。本篇随笔主要介绍车牌定位及畸变校正两部分,在python环境下通过opencv实现。

1.1 车牌定位

目前主流的车牌定位方法从大的方面来说可以分为两类:一种是基于车牌的背景颜色特征;另一种基于车牌的轮廓形状特征。基于颜色特征的又可分为两类:一种在RGB空间识别,另一种在HSV空间识别。经测试后发现,单独使用任何一种方法,效果均不太理想。目前比较普遍的做法是几种定位方法同时使用,或用一种识别,另一种验证。本文主要通过颜色特征对车牌进行定位,以HSV空间的H分量为主,以RGB空间的R分量和B分量为辅,后续再用车牌的长宽比例排除干扰。

1.2 畸变校正

在车牌的图像采集过程中,相机镜头通常都不是垂直于车牌的,所以待识别图像中车牌或多或少都会有一定程度的畸变,这给后续的车牌内容识别带来了一定的困难。因此需要对车牌进行畸变校正,消除畸变带来的不利影响。

2 代码实现

2.1 车牌定位

2.1.1 通过颜色特征选定可疑区域

取了不同光照环境下车牌的图像,截取其背景颜色,利用opencv进行通道分离和颜色空间转换,经试验后,总结出车牌背景色的以下特征:

  • (1)在HSV空间下,H分量的值通常都在115附近徘徊,S分量和V分量因光照不同而差异较大(opencv中H分量的取值范围是0到179,而不是图像学中的0到360;S分量和V分量的取值范围是到255);

  • (2)在RGB空间下,R分量通常较小,一般在30以下,B分量通常较大,一般在80以上,G分量波动较大;

  • (3)在HSV空间下对图像进行补光和加饱和度处理,即将图像的S分量和V分量均置为255,再进行色彩空间转换,由HSV空间转换为RGB空间,发现R分量全部变为0,B分量全部变为255(此操作会引入较大的干扰,后续没有使用)。

根据以上特征可初步筛选出可疑的车牌区域。随后对灰度图进行操作,将可疑位置的像素值置为255,其他位置的像素值置为0,即根据特征对图像进行了二值化。二值化图像中,可疑区域用白色表示,其他区域均为黑色。随后可通过膨胀腐蚀等操作对图像进一步处理。

for i in range(img_h):for j in range(img_w):# 普通蓝色车牌,同时排除透明反光物质的干扰if ((img_HSV[:, :, 0][i, j]-115)**2 < 15**2) and (img_B[i, j] > 70) and (img_R[i, j] < 40):img_gray[i, j] = 255else:img_gray[i, j] = 0

在这里插入图片描述

2.1.2 寻找车牌外围轮廓

选定可疑区域并将图像二值化后,一般情况下,图像中就只有车牌位置的像素颜色为白,但在一些特殊情况下还会存在一些噪声。如上图所示,由于图像右上角存在蓝色支架,与车牌颜色特征相符,因此也被当做车牌识别了出来,由此引入了噪声。

经过观察可以发现,车牌区域与噪声之间存在较大的差异,且车牌区域特征比较明显:

  • (1)根据我国常规车牌的形状可知,车牌的形状为扁平矩形,长宽比约为3:1;

  • (2)车牌区域面积远大于噪声区域,一般为图像中最大的白色区域。

在这里插入图片描述

可以通过cv2.findContours()函数寻找二值化后图像中白色区域的轮廓。

注意:在opencv2和opencv4中,cv2.findContours()的返回值有两个,而在opencv3中,返回值有3个。视opencv版本不同,代码的写法也会存在一定的差异。

# 检测所有外轮廓,只留矩形的四个顶点
# opencv4.0, opencv2.x
contours, _ = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# opencv3.x
_, contours, _ = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

这里,因为二值化图像中共有三块白色区域(车牌及两处噪声),因此返回值contours为长度为3的list。list内装有3个array,每个array内各存放着一块白色区域的轮廓信息。每个array的shape均为(n,
1, 2),即每个array存放着对应白色区域轮廓上n个点的坐标。

目前得到了3个array,即3组轮廓信息,但我们并不清楚其中哪个是车牌区域对应的那一组轮廓信息。此时可以根据车牌的上述特征筛选出车牌区域的轮廓。

#形状及大小筛选校验
det_x_max = 0
det_y_max = 0
num = 0
for i in range(len(contours)):x_min = np.min(contours[i][ :, :, 0])x_max = np.max(contours[i][ :, :, 0])y_min = np.min(contours[i][ :, :, 1])y_max = np.max(contours[i][ :, :, 1])det_x = x_max - x_mindet_y = y_max - y_minif (det_x / det_y > 1.8) and (det_x > det_x_max ) and (det_y > det_y_max ):det_y_max = det_ydet_x_max = det_xnum = i
# 获取最可疑区域轮廓点集
points = np.array(contours[num][:, 0])

最终得到的points的shape为(n, 2),即存放了n个点的坐标,这n个点均分布在车牌的边缘上

2.1.3 车牌区域定位

获取车牌轮廓上的点集后,可用cv2.minAreaRect()获取点集的最小外接矩形。返回值rect内包含该矩形的中心点坐标、高度宽度及倾斜角度等信息,使用cv2.boxPoints()可获取该矩形的四个顶点坐标。

# 获取最小外接矩阵,中心点坐标,宽高,旋转角度
rect = cv2.minAreaRect(points)
# 获取矩形四个顶点,浮点型
box = cv2.boxPoints(rect)
# 取整
box = np.int0(box)

但我们并不清楚这四个坐标点各对应着矩形的哪一个顶点,因此无法充分地利用这些坐标信息。

可以从坐标值的大小特征入手,将四个坐标与矩形的四个顶点匹配起来:在opencv的坐标体系下,纵坐标最小的是top_point,纵坐标最大的是bottom_point,
横坐标最小的是left_point,横坐标最大的是right_point。

# 获取四个顶点坐标
left_point_x = np.min(box[:, 0])
right_point_x = np.max(box[:, 0])
top_point_y = np.min(box[:, 1])
bottom_point_y = np.max(box[:, 1])left_point_y = box[:, 1][np.where(box[:, 0] == left_point_x)][0]
right_point_y = box[:, 1][np.where(box[:, 0] == right_point_x)][0]
top_point_x = box[:, 0][np.where(box[:, 1] == top_point_y)][0]
bottom_point_x = box[:, 0][np.where(box[:, 1] == bottom_point_y)][0]
# 上下左右四个点坐标
vertices = np.array([[top_point_x, top_point_y], [bottom_point_x, bottom_point_y], [left_point_x, left_point_y], [right_point_x, right_point_y]])

在这里插入图片描述
在这里插入图片描述

2.2 畸变校正

2.2.1 畸变后车牌顶点定位

要想实现车牌的畸变矫正,必须找到畸变前后对应点的位置关系。

可以看出,本是矩形的车牌畸变后变成了平行四边形,因此车牌轮廓和得出来的矩形轮廓并不契合。但有了矩形的四个顶点坐标后,可以通过简单的几何相似关系求出平行四边形车牌的四个顶点坐标。

在本例中,平行四边形四个顶点与矩形四个顶点之间有如下关系:矩形顶点Top_Point、Bottom_Point与平行四边形顶点new_top_point、new_bottom_point重合,矩形顶点Top_Point的横坐标与平行四边形顶点new_right_point的横坐标相同,矩形顶点Bottom_Point的横坐标与平行四边形顶点new_left_point的横坐标相同。

在这里插入图片描述

但事实上,由于拍摄的角度不同,可能出现两种不同的畸变情况。可以根据矩形倾斜角度的不同来判断具体是哪种畸变情况。

在这里插入图片描述

判断出具体的畸变情况后,选用对应的几何相似关系,即可轻易地求出平行四边形四个顶点坐标,即得到了畸变后车牌四个顶点的坐标。

要想实现车牌的校正,还需得到畸变前车牌四个顶点的坐标。因为我国车牌的标准尺寸为440X140,因此可规定畸变前车牌的四个顶点坐标分别为:(0,0),(440,0),(0,140),(440,140)。顺序上需与畸变后的四个顶点坐标相对应。

# 畸变情况1
if rect[2] > -45:new_right_point_x = vertices[0, 0]new_right_point_y = int(vertices[1, 1] - (vertices[0, 0]- vertices[1, 0]) / (vertices[3, 0] - vertices[1, 0]) * (vertices[1, 1] - vertices[3, 1]))new_left_point_x = vertices[1, 0]new_left_point_y = int(vertices[0, 1] + (vertices[0, 0] - vertices[1, 0]) / (vertices[0, 0] - vertices[2, 0]) * (vertices[2, 1] - vertices[0, 1]))# 校正后的四个顶点坐标point_set_1 = np.float32([[440, 0],[0, 0],[0, 140],[440, 140]])
# 畸变情况2
elif rect[2] < -45:new_right_point_x = vertices[1, 0]new_right_point_y = int(vertices[0, 1] + (vertices[1, 0] - vertices[0, 0]) / (vertices[3, 0] - vertices[0, 0]) * (vertices[3, 1] - vertices[0, 1]))new_left_point_x = vertices[0, 0]new_left_point_y = int(vertices[1, 1] - (vertices[1, 0] - vertices[0, 0]) / (vertices[1, 0] - vertices[2, 0]) * (vertices[1, 1] - vertices[2, 1]))# 校正后的四个顶点坐标point_set_1 = np.float32([[0, 0],[0, 140],[440, 140],[440, 0]])# 校正前平行四边形四个顶点坐标
new_box = np.array([(vertices[0, 0], vertices[0, 1]), (new_left_point_x, new_left_point_y), (vertices[1, 0], vertices[1, 1]), (new_right_point_x, new_right_point_y)])
point_set_0 = np.float32(new_box)

2.2.2 校正

该畸变是由于摄像头与车牌不垂直而引起的投影造成的,因此可用cv2.warpPerspective()来进行校正。

# 变换矩阵
mat = cv2.getPerspectiveTransform(point_set_0, point_set_1)
# 投影变换
lic = cv2.warpPerspective(img, mat, (440, 140))

在这里插入图片描述

import cv2import numpy as np# 预处理def imgProcess(path):img = cv2.imread(path)# 统一规定大小img = cv2.resize(img, (640,480))# 高斯模糊img_Gas = cv2.GaussianBlur(img,(5,5),0)# RGB通道分离img_B = cv2.split(img_Gas)[0]img_G = cv2.split(img_Gas)[1]img_R = cv2.split(img_Gas)[2]# 读取灰度图和HSV空间图img_gray = cv2.cvtColor(img_Gas, cv2.COLOR_BGR2GRAY)img_HSV = cv2.cvtColor(img_Gas, cv2.COLOR_BGR2HSV)return img, img_Gas, img_B, img_G, img_R, img_gray, img_HSV# 初步识别def preIdentification(img_gray, img_HSV, img_B, img_R):for i in range(480):for j in range(640):# 普通蓝色车牌,同时排除透明反光物质的干扰if ((img_HSV[:, :, 0][i, j]-115)**2 < 15**2) and (img_B[i, j] > 70) and (img_R[i, j] < 40):img_gray[i, j] = 255else:img_gray[i, j] = 0# 定义核kernel_small = np.ones((3, 3))kernel_big = np.ones((7, 7))img_gray = cv2.GaussianBlur(img_gray, (5, 5), 0) # 高斯平滑img_di = cv2.dilate(img_gray, kernel_small, iterations=5) # 腐蚀5次img_close = cv2.morphologyEx(img_di, cv2.MORPH_CLOSE, kernel_big) # 闭操作img_close = cv2.GaussianBlur(img_close, (5, 5), 0) # 高斯平滑_, img_bin = cv2.threshold(img_close, 100, 255, cv2.THRESH_BINARY) # 二值化return img_bin# 定位def fixPosition(img, img_bin):# 检测所有外轮廓,只留矩形的四个顶点contours, _ = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)#形状及大小筛选校验det_x_max = 0det_y_max = 0num = 0for i in range(len(contours)):x_min = np.min(contours[i][ :, :, 0])x_max = np.max(contours[i][ :, :, 0])y_min = np.min(contours[i][ :, :, 1])y_max = np.max(contours[i][ :, :, 1])det_x = x_max - x_mindet_y = y_max - y_minif (det_x / det_y > 1.8) and (det_x > det_x_max ) and (det_y > det_y_max ):det_y_max = det_ydet_x_max = det_xnum = i# 获取最可疑区域轮廓点集points = np.array(contours[num][:, 0])return points#img_lic_canny = cv2.Canny(img_lic_bin, 100, 200)def findVertices(points):# 获取最小外接矩阵,中心点坐标,宽高,旋转角度rect = cv2.minAreaRect(points)# 获取矩形四个顶点,浮点型box = cv2.boxPoints(rect)# 取整box = np.int0(box)# 获取四个顶点坐标left_point_x = np.min(box[:, 0])right_point_x = np.max(box[:, 0])top_point_y = np.min(box[:, 1])bottom_point_y = np.max(box[:, 1])left_point_y = box[:, 1][np.where(box[:, 0] == left_point_x)][0]right_point_y = box[:, 1][np.where(box[:, 0] == right_point_x)][0]top_point_x = box[:, 0][np.where(box[:, 1] == top_point_y)][0]bottom_point_x = box[:, 0][np.where(box[:, 1] == bottom_point_y)][0]# 上下左右四个点坐标vertices = np.array([[top_point_x, top_point_y], [bottom_point_x, bottom_point_y], [left_point_x, left_point_y], [right_point_x, right_point_y]])return vertices, rectdef tiltCorrection(vertices, rect):# 畸变情况1if rect[2] > -45:new_right_point_x = vertices[0, 0]new_right_point_y = int(vertices[1, 1] - (vertices[0, 0]- vertices[1, 0]) / (vertices[3, 0] - vertices[1, 0]) * (vertices[1, 1] - vertices[3, 1]))new_left_point_x = vertices[1, 0]new_left_point_y = int(vertices[0, 1] + (vertices[0, 0] - vertices[1, 0]) / (vertices[0, 0] - vertices[2, 0]) * (vertices[2, 1] - vertices[0, 1]))# 校正后的四个顶点坐标point_set_1 = np.float32([[440, 0],[0, 0],[0, 140],[440, 140]])# 畸变情况2elif rect[2] < -45:new_right_point_x = vertices[1, 0]new_right_point_y = int(vertices[0, 1] + (vertices[1, 0] - vertices[0, 0]) / (vertices[3, 0] - vertices[0, 0]) * (vertices[3, 1] - vertices[0, 1]))new_left_point_x = vertices[0, 0]new_left_point_y = int(vertices[1, 1] - (vertices[1, 0] - vertices[0, 0]) / (vertices[1, 0] - vertices[2, 0]) * (vertices[1, 1] - vertices[2, 1]))# 校正后的四个顶点坐标point_set_1 = np.float32([[0, 0],[0, 140],[440, 140],[440, 0]])# 校正前平行四边形四个顶点坐标new_box = np.array([(vertices[0, 0], vertices[0, 1]), (new_left_point_x, new_left_point_y), (vertices[1, 0], vertices[1, 1]), (new_right_point_x, new_right_point_y)])point_set_0 = np.float32(new_box)return point_set_0, point_set_1, new_boxdef transform(img, point_set_0, point_set_1):# 变换矩阵mat = cv2.getPerspectiveTransform(point_set_0, point_set_1)# 投影变换lic = cv2.warpPerspective(img, mat, (440, 140))return licdef main():path = 'F:\\Python\\license_plate\\test\\9.jpg'# 图像预处理img, img_Gas, img_B, img_G, img_R, img_gray, img_HSV = imgProcess(path)# 初步识别img_bin  = preIdentification(img_gray, img_HSV, img_B, img_R)points = fixPosition(img, img_bin)vertices, rect = findVertices(points)point_set_0, point_set_1, new_box = tiltCorrection(vertices, rect)img_draw = cv2.drawContours(img.copy(), [new_box], -1, (0,0,255), 3)lic = transform(img, point_set_0, point_set_1)# 原图上框出车牌cv2.namedWindow("Image")cv2.imshow("Image", img_draw)# 二值化图像cv2.namedWindow("Image_Bin")cv2.imshow("Image_Bin", img_bin)# 显示校正后的车牌cv2.namedWindow("Lic")cv2.imshow("Lic", lic)# 暂停、关闭窗口cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':main()

在这里插入图片描述

7 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

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

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

相关文章

Leetcode3192. 使二进制数组全部等于 1 的最少操作次数 II

Every day a Leetcode 题目来源&#xff1a;3192. 使二进制数组全部等于 1 的最少操作次数 II 解法1&#xff1a;遍历 由于 nums[i] 会被其左侧元素的操作影响&#xff0c;所以我们先从最左边的 nums[0] 开始思考。 分类讨论&#xff1a; 如果 nums[0]1&#xff0c;无需反…

amis-editor 注册自定义组件

建议先将amis文档从头到尾&#xff0c;仔细看一遍。 参考&#xff1a;amis - 低代码前端框架 amis 的渲染过程是将 json 转成对应的 React 组件。先通过 json 的 type 找到对应的 Component&#xff0c;然后把其他属性作为 props 传递过去完成渲染。 import * as React from …

flex讲解

随着前端技术的不断发展和更新&#xff0c;flex布局成为前端布局的主流。但是仍然有很多前端新手搞不懂flex到底怎么用&#xff01;&#xff01;&#xff01;今天我们就来好好讲讲flex布局 老规矩先上定义 什么是flex布局 布局的传统解决方案&#xff0c;基于盒状模型&#x…

郑州高校大学智能制造实验室数字孪生可视化系统平台建设项目验收

随着制造业的转型升级&#xff0c;智能化、信息化已成为制造业发展的必然趋势。数字孪生技术作为智能制造领域的关键技术之一&#xff0c;它通过构建与实体系统相对应的虚拟模型&#xff0c;实现对实体系统的实时监测、预测和优化&#xff0c;为制造业的智能化、信息化提供了强…

LitelDE安装---附带每一步截图以及测试

LiteIDE LiteIDE 是一款专为Go语言开发而设计的开源、跨平台、轻量级集成开发环境&#xff08;IDE&#xff09;&#xff0c;基于 Qt 开发&#xff08;一个跨平台的 C 框架&#xff09;&#xff0c;支持 Windows、Linux 和 Mac OS X 平台。LiteIDE 的第一个版本发布于 2011 年 …

PTA-线性表实验(JAVA)

题目1&#xff1a;Josephus环的问题及算法 【实验内容】 编程实现如下功能&#xff1a; 题意说明&#xff1a;古代某法官要判决n个犯人的死刑&#xff0c;他有一条荒唐的法律&#xff0c;将犯人站成一个圆圈&#xff0c;从第start个犯人开始数起&#xff0c;每数到第distance的…

使用Dockerfile构建镜像 使用docker-compose 一键部署IM项目

本文讲解&#xff1a;使用Dockerfile构建镜像 & 使用docker-compose 一键部署IM项目。 im项目地址&#xff1a;xzll-im &#xff0c;欢迎志同道合的开发者 一起 维护&#xff0c;学习&#xff0c;欢迎star &#x1f604; 1、Dockerfile编写与镜像构建&容器运行 Dockerf…

Nginx和CDN运用

一.Web缓存代理 1.工作机制 代替客户机向网站请求数据&#xff0c;从而可以隐藏用户的真实IP地址。将获得的网页数据&#xff08;静态Web元素&#xff09;保存到缓存中并发送给客户机&#xff0c;以便下次请求相同的数据时快速响应。 2.代理服务器的概念 代理服务器是一个位…

k8s token加新节点

在 master 节点执行 kubeadm token create --print-join-command得到token和cert&#xff0c;这两个参数在2个小时内可以重复使用&#xff0c;超过以后就得再次生成 kubeadm join apiserver.k8s.com --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha…

【入门】5分钟了解卷积神经网络CNN是什么

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ 目录 一、卷积神经网络的结构1.1.卷积与池化的作用2.2.全连接层的作用 二、卷积神经网络的运算2.1.卷积层的运算2.2.池化的运算2.3.全连接层运算 三、pytorch实现一个CNN例子3.1.模型的搭建3.2.CNN完整训练代码 CNN神…

【Dison夏令营 Day 04】如何用 Python 编写简单的数字猜谜游戏代码

上个周末&#xff0c;我整理了一份可以用 Python 编写的游戏列表。但为什么呢&#xff1f; 如果您是 Python 程序员初学者&#xff0c;编写有趣的游戏可以帮助您更快更好地学习 Python 语言&#xff0c;而不会被语法之类的东西所困扰。我在学习 Python 的时候曾制作过一些这样…

Hadoop-03-Hadoop集群 免密登录 超详细 3节点公网云 分发脚本 踩坑笔记 SSH免密 服务互通 集群搭建 开启ROOT

章节内容 上一节完成&#xff1a; HDFS集群XML的配置MapReduce集群XML的配置Yarn集群XML的配置统一权限DNS统一配置 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&…

短视频矩阵系统搭建APP源码开发

前言 短视频矩阵系统不仅有助于提升品牌影响力和营销效率&#xff0c;还能帮助企业更精准地触达目标受众&#xff0c;增强用户互动&#xff0c;并利用数据分析来持续优化营销策略。 一、短视频矩阵系统是什么&#xff1f; 短视频矩阵系统是一种通过多个短视频平台进行内容创作…

多多代播24小时值守:电商直播时代是带货爆单的关键

在电商直播盛行的今天&#xff0c;直播带货已成为品牌与消费者沟通的关键。然而&#xff0c;流量波动大&#xff0c;竞争激烈&#xff0c;使品牌面临诸多挑战。因此&#xff0c;许多品牌寻求专业代播服务&#xff0c;并特别强调24小时值守的重要性。 流量来源的不稳定性是一个显…

Linux下安装RocketMQ:从零开始的消息中间件之旅

感谢您阅读本文&#xff0c;欢迎“一键三连”。作者定会不负众望&#xff0c;按时按量创作出更优质的内容。 ❤️ 1. 毕业设计专栏&#xff0c;毕业季咱们不慌&#xff0c;上千款毕业设计等你来选。 RocketMQ是一款分布式消息中间件&#xff0c;具有高吞吐量、低延迟、高可用性…

本末倒置!做660+880一定要避免出现这3种情况!

每年都有不少人做过660题&#xff0c;但是做过之后&#xff0c;并没有真正理解其中的题目&#xff0c;所以做过之后效果也不好&#xff01;再去做880题&#xff0c;做的也会比较吃力。 那该怎么办呢&#xff0c;不建议你继续做880题&#xff0c;先把660给吃透再说。 接下来给…

PostgreSQL使用教程

安装 PostgreSQL 您可以从 PostgreSQL 官方网站下载适合您操作系统的安装程序&#xff0c;并按照安装向导进行安装。 启动数据库服务器 安装完成后&#xff0c;根据您的操作系统&#xff0c;通过相应的方式启动数据库服务器。 连接到数据库 可以使用命令行工具&#xff08;如 p…

Objective-C使用块枚举的细节

对元素类型的要求 在 Objective-C 中&#xff0c;NSArray 只能存储对象类型&#xff0c;而不能直接存储基本类型&#xff08;例如 int&#xff09;。但是&#xff0c;可以将基本类型封装在 NSNumber 等对象中&#xff0c;然后将这些对象存储在 NSArray 中。这样&#xff0c;en…

Maven编译打包时报“PKIX path building failed”异常

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 方法11.报错信息2.InstallCert.java3.生成证书文件 jssecacerts4.复制 jssecacerts 文件5. 然后重启Jenkins 或者maven即可 方法21.下载证书2. 导入证书执行keytool…

7.优化算法之分治-快排归并

0.分治 分而治之 1.颜色分类 75. 颜色分类 - 力扣&#xff08;LeetCode&#xff09; 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数…