本文针对智慧社区里面的两个典型场景:高空抛物和车牌识别,记录评测了基于AidLux平台的算法开发以及边缘部署的过程。

1智慧社区的背景

1.1智慧社区的各类场景算法的划分

智慧社区主要分成以下三个方面:住房安全管控、社区环境管控以及物业服务管控三个部分。住房安全管控,主要包括消防安全的监管和入侵安全之类。社区环境管控,主要是对小区内的公共环境实时监测。物业服务管控,主要是包括提升物业效率的智能化管控。

每个场景都对应着不同的算法业务功能,每个算法业务功能则是由不同的算法框架如:目标检测、图像分类、人脸检索等组合而成。

1.2智慧社区项目落地方式

一般的项目算法开发流程:

产品的开发流程,相对于项目的开发流程在整体上差不多,产品需求的明确性相对与项目稍差,同时涉及到投入市场后的用户反应等因素,所以需求变更稍频繁,同时考虑后期的拓展性等问题,在算法方案和算法接口上会考虑更多

算法项目,会有验收指标,但是如果有的客户对算法了解不多,需要算法参与指导制定验收指标。算法的评价分为两种:一种是算法模型的评价,另外一种是项目业务的评价

1.3边缘设备在智慧社区中的应用场景

现在外界很流行端边云协同系统,即指把简单的、需要实时计算和分析的过程放到离终端设备更近的地方,以保证数据数据处理的实时性,同时也减少数据传输的风险。

整体上说是边缘负责局部的数据分析和推理,而云端则汇集所有边缘的感知数据、业务数据以及互联网数据,完成对行业以及跨行业的态势感知和分析,而端指的是终端设备,如手机、智能家电、摄像头等。

2高空抛物识别

2.1背景简介

高空抛物是智慧社区的重要部分之一,主要为主动识别高空中抛下的物体,一般场景为以监看和事后取证为主。

我们在很多小区经常会看到类似的高空抛物相机,以仰视的角度,往住宅楼的角度拍摄,当发生抛物事件的时候,可以实时的监测到,当发生危险事故时,可以实时的去追踪,查看当时高空抛物的视频,追踪到底是从哪家的窗口抛出的。

2.2方案设计

难点在于以下几点:

(1)抛出的物体相对于整个楼栋的目标太小;

(2)干扰因素较多,如白天的飞鸟、飘落的树叶、夜晚的背景楼栋灯光等;

(3)环境影响如雨天、雾天、逆光等环境对结果影响较大。

2.2.1数据采集

难点在于相机的位置和角度的安装。对于不同的层高,建议的安装距离和分辨率选择对应的相机焦距不同。针对夜间低照度,小区夜间光照不足,不建议通过补光的方式来提高环境照度,这样的环境下可以选型超星光摄像头,最低支持0.0002lux。白天高空抛物摄像头对着天空,白天有强烈的太阳光会造成逆光现象,可以选型摄像头支持120db的宽动态摄像头,同时也支持背光补偿。

2.2.2算法设计

1. 使用传统的动态目标检测,如光流检测和帧差法;

2. 使用目标检测+目标追踪算法,对抛出的物体先做目标检测,并对检测到的物体做追踪;

3. 使用物体追踪+过滤算法;

4.  使用视频分类的算法。

对于第一种方法传统方法的动态目标检测,如光流检测和帧差法,稳定性稍差,优点在于对于数据要求低。

对于第二种方法,使用目标检测检测被抛物体,并通过目标追踪对抛出物体的运动轨迹做追踪,会受到背景的影响很大,因为楼宇间的灯光等,同时使用目标检测+目标追踪的方法,其难点在于小目标的检测,很容易出现漏检

对于第三种方法,针对第二种方法中的目标检测算法的效果不佳,采用高斯背景建模的方法,过滤背景信息。再使用目标追踪如kalman滤波,完成运动轨迹的记录,同时针对第二种方法中视频中会出现的树叶、飞鸟以及晒衣服等的摆动等不符合抛物运动的轨迹的误检,通过SOM网络进行聚类,SOM(自组织映射神经网络)会对不同运动的轨迹进行分析:排除掉不符合抛物运动的轨迹

对于第四种方法,使用视频分类的方式,即对一段时间内的视频流做视频分类,这里可以通过第三步中先通过视频抽帧完成高斯背景建模,过滤掉背景后,再对前处理后的视频完成视频的分类。

本文主要选择第一种方法。

2.3算法实现

流程是先在PC端完成算法的实现后,再移植到安卓端。

2.3.1去抖动

背景建模的前提是保证摄像机拍摄位置不变,保证背景是基本不发生变化的。

其主要的原理是通过每张图的特征,找到两个图片的关键点,并基于关键点获得变换矩阵后,将原图通过变换矩阵变换后,与第一张原始图片对齐。

   def debouncing(self, image, index, ratio=0.7, reprojThresh=4.0, showMatches=False):image = cv2.resize(image, (int(image.shape[1]/1), int(image.shape[0]/1))) # 截帧图片的长宽的量化start = time.time() (kps, features) = self.detectAndDescribe(image) # 对图片灰度化,并基于ORB算法,定位到关键点print(f"take {time.time() - start} s") M = self.matchKeypoints(kps, self.kps, features, self.features, ratio, reprojThresh) # 基于每一帧与背景帧,完成关键点的匹配,输出匹配变换矩阵、if M is None:return None(matches, H, status) = M"""将图像按照变换映射M执行后返回变换后的图像result。参数: * src input image.* dst output image that has the size dsize and the same type as src .* M  $ 3\cdot 3 $ transformation matrix.* dsize size of the output image.* flags  combination of interpolation methods (INTER_LINEAR or INTER_NEAREST) and the optional flag WARP_INVERSE_MAP, that sets M as the inverse transformation ( $\text{dst}\to \text{src}$ ).* borderMode  pixel extrapolation method (BORDER_CONSTANT or BORDER_REPLICATE).* borderValue  value used in case of a constant border; by default, it equals 0."""result = cv2.warpPerspective(image, H, (image.shape[1] + image.shape[1], image.shape[0] + image.shape[0])) # 填充图片 opencv显示结果result = result[int(self.edge[1]):int(image.shape[0] - self.edge[1]),int(self.edge[0]):int(image.shape[1] - self.edge[0])]start_img = self.start_image[int(self.edge[1]):int(image.shape[0] - self.edge[1]),int(self.edge[0]):int(image.shape[1] - self.edge[0])]# 获取两张图的差分图sub_img = cv2.absdiff(result, start_img)return result

2.3.2背景建模

背景建模主要是为了检测运动物体,输出前景图片。

class knnDetector:def __init__(self, history, dist2Threshold, minArea):self.minArea = minArea """此算法结合了静态背景图像估计和每个像素的贝叶斯分割。这是 2012 年Andrew_B.Godbehere,Akihiro_Matsukawa 和 Ken_Goldberg 在文章中提出的。它使用前面很少的图像(默认为前 120 帧)进行背景建模。使用了概率前景估计算法(使用贝叶斯估计鉴定前景)。这是一种自适应的估计,新观察到的对象比旧的对象具有更高的权重,从而对光照变化产生适应。一些形态学操作如开运算闭运算等被用来除去不需要的噪音。在前几帧图像中你会得到一个黑色窗口。对结果进行形态学开运算对与去除噪声帮助背景重建方法:MOG2 /knn """self.detector = cv2.createBackgroundSubtractorKNN(history, dist2Threshold, False) # 背景建模"""# 得到一个结构元素(卷积核)。主要用于后续的腐蚀、膨胀、开、闭等运算。因为这些运算都是依赖于卷积核的,不同的卷积核(形状、大小)对图形的腐蚀、膨胀操作效果不一样输入参数:a设定卷积核的形状、b设定卷积核的大小、c表示描点的位置,一般 c = 1, 表示描点位于中心。返回值:返回指定形状和尺寸的结构元素(一般是返回一个矩形)、也就是腐蚀/膨胀用的核的大小。"""self.kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # def detectOneFrame(self, frame,index):if frame is None:return Nonestart = time.time()mask = self.detector.apply(frame) # 背景重建,提取前景 # if index% 10 == 0 :#    cv2.imwrite(os.path.join(r"C:\Users\shime\Desktop\highthrow(1)\images", "mask_unprocess_{index}.jpg".format(index=index)), mask)stop = time.time()print("detect cast {} ms".format(stop - start))# cv2.namedWindow("mask_unprocess", cv2.WINDOW_NORMAL)# cv2.imshow("mask_unprocess", mask)start = time.time()mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, self.kernel) # 做开运算 先腐蚀,再膨胀# if index% 10 == 0 :#    cv2.imwrite(os.path.join(r"C:\Users\shime\Desktop\highthrow(1)\images", "mask_process_open_{index}.jpg".format(index=index)), mask)mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, self.kernel) # 再膨胀# if index% 10 == 0 :#    cv2.imwrite(os.path.join(r"C:\Users\shime\Desktop\highthrow(1)\images", "mask_process_dilate_{index}.jpg".format(index=index)), mask)stop = time.time()print("open contours cast {} ms".format(stop - start))start = time.time()contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 基于mask提取轮廓stop = time.time()print("find contours cast {} ms".format(stop - start))i = 0bboxs = []start = time.time()for c in contours:i += 1if cv2.contourArea(c) < self.minArea: # 过滤continuebboxs.append(cv2.boundingRect(c)) # 基于轮廓 寻找外接矩形 stop = time.time()print("select cast {} ms".format(stop - start))return mask, bboxs

2.3.3形态学处理

前景的mask 中存在很多的干扰,如灯光的干扰等,再通过形态学处理将干扰项移除。

2.3.4目标检测

在第三步过滤掉干扰过后,找到目标的外接轮廓,同时过滤掉小的斑点干扰后,提取目标的外接矩形。

2.3.5目标追踪

SORT是 SIMPLE ONLINE AND REALTIME TRACKING 的简写,并不是什么排序算法。

其核心算法是匈牙利算法+卡尔曼滤波。

SORT算法没有用到特征跟踪,其本质实际上是根据观测的位置预测下一帧出现的位置,而我们预测的高空抛物实际上是有很强的规律的(重物规律强,较轻的物体如塑料袋或者纸板等,不是很规律,但是其速度不快,在每一帧之间基本上都有IOU重叠,因此也不会漏检),所以完全可以用此算法。

2.4基于Aidlux平台的部署和推理测试

2.4.1平台简介

Idlux主打的是基于ARM架构的跨生态(Android/鸿蒙+Linux)一站式AIOT应用开发平台。用比较简单的方式理解,我们平时编写训练模型,测试模型的时候,常用的是Linux/window系统。而实际部署到现场的时候,通常会以几种形态:GPU服务器、嵌入式设备(比如Android手机、人脸识别闸机等)、边缘设备。GPU服务器我们好理解,而Android嵌入式设备的底层芯片,通常是ARM架构。而Linux底层也是ARM架构,并且Android又是基于Linux内核开发的操作系统,两者可以共享Linux内核。因此就产生了从底层开发一套应用系统的方式,在此基础上同时带来原生Android和原生Linux使用体验。基于ARM芯片,阿加犀开发了Aidlux平台,可以在安卓手机上直接下载Aidlux使用。

再看一下常规的方式,我们想要将算法应用在手机Android时,需要将PC上编写的Python代码,封装成Android SO库(C++)。经过测试后,封装JNI调用SO库,最终在Android上使用Java调用JNI,最终再进行测试发布。因此我们可以看到,这样的流程需要一系列的工作人员参与,比如C++、Java、Python的工程师。但是大多数算法人员可能会用Python更多一些,比如上面编写的整套算法。Aidlux将其中的整个开发流程,全部打通,通过Aidlux平台,可以将PC端编写的代码,快速应用到Android系统上。

同时芯片对于AI算法的优化加速的能力。Aidlux内部一方面内置了多种深度学习框架,便于快速开发。另外对于多种算子进行了优化加速,很多算法的性能,也都能达到实时使用。

2.4.2平台使用

使用Aidlux主要有两种方式

(1)边缘设备的方式:阿加犀用高通芯片的S855,和S865制作了两款边缘设备,一款提供7T算力,一款提供15T算力

(2)手机设备的方式:没有边缘设备的情况下,也可以使用手机版本的Aidlux,尝试边缘设备的所有功能。

并且目前Aidlux已对基本市面上所有的芯片都进行了适配,在手机上运行算法模型,也可以体验优化的效果。当然在使用过程中,有个共同点,即手机设备和边缘设备采用的Aidlux软件,都是一样的。因此可以先尝试手机设备的方式,在后期需要更多算力的时候,使用边缘设备,就可以无缝衔接。打开安卓手机的应用商城,搜索Aidlux即可下载安装。具体使用方法可参加相关链接。

2.4.3算法部署

在平台上直接修改和运行代码不方便。而远程连接的方式有两种:基于Vscode的远程连接,和基于浏览器的远程连接。

基于浏览器的远程连接:

 基于Vscode的远程连接:

安装环境:

conda create -n aidadao python=3.9
conda activate aidadao
pip install scikit-image
pip install opencv-python
pip install matplotlib

从参考连接下载代码。在测试视频中,180帧开始出现高空抛物。

移动端适配。在移动端,android端的代码在aidlux_highBuildingThrow文件夹中,在main文件中,导入opencv 使用同时我们使用的是cvs的方式来显示图片:

from cvs import *
path = "IMG_4550.MOV"
capture = cvs.VideoCapture(path) # 获取视频
capture.set(cvs.CAP_PROP_POS_FRAMES, 200) # 设置视频从第几帧开始读取
frame = capture.read() # 读取初始视频帧
while True:frame = capture.read()if frame is None:break
cvs.imshow(frame)

2.4.4应用展示

运行主函数:

## PC端运行
cd D:\code\aidlux_dd\高空抛物\highthrow_b
python main.py
## 移动端运行
cd /home/xly3dd/aidlux_highBuildingThrow
python main.py

PC端运行结果:

移动端运行结果:

 由上图可见,移动端运行速度相较PC端慢很多,这是由于测试手机端算力有限。

修改代码中参数:

parser.add_argument("--max_age", help="Maximum number of frames to keep alive a track without associated detections.", type=int, default=1)
parser.add_argument("--min_hits", help="Minimum number of associated detections before track is initialised.", type=int, default=3)
parser.add_argument("--iou_threshold", help="Minimum IOU for match.", type=float, default=0.3)
class Sort(object):def __init__(self, max_age=1, min_hits=3, iou_threshold=0.3):

改变参数max_age:较小,跟踪容易丢失;较大,会保存过多冗余的状态。

sort = Sort(1, 5, 0.1) ## max_age:较小,跟踪容易丢失;较大,会保存过多冗余的状态

视频:

SVID_20230227_000906_1

改变参数min_hits:较小,容易误跟踪;较大,跟踪较迟钝。

sort = Sort(3, 9, 0.1) ## min_hits:较小,容易误跟踪;较大,跟踪较迟钝

视频:

SVID_20230227_215441_1

3车辆车牌识别

3.1背景简介

在检测到车后,再对车进行车牌的检测和识别。

3.2方案设计

开源车牌数据集是中科大的CCPD数据集,官网链接是:GitHub - detectRecog/CCPD: [ECCV 2018] CCPD: a diverse and well-annotated dataset for license plate detection and recognition

中科大车牌数据集有CCPD2019和CCPD2020,其中CCPD2019主要为蓝牌,CCPD2020为绿牌。

涉及算法:(车辆检测+)车牌检测+车牌识别

涉及模型:车牌检测的yolov5模型和车牌识别的LPRNet模型

车牌识别的方案主要有两种:一种是粗粒度的:车牌检测+车牌识别另外一种细粒度的:车牌检测+车牌矫正+车牌识别。

3.3算法实现

3.2.1划分数据集

按比例划分训练集和测试集

3.2.2训练

训练车牌检测模型:python tools/train_yolov5.py

得到模型:yolov5_best.pt

训练车牌识别模型:python train_lprnet.py

得到模型:lprnet_best.pth

3.2.3测试

修改各个脚本的权重文件路径,测试数据集路径等。

终端输入:python detect_yolov5.py

终端输入:python test_lprnet.py

将车牌检测+识别的算法串起来,即车牌检测+识别的pipeline,即为我们的代码的detect_torch_pipeline.py

修改中文字体:

## D:\code\aidlux_dd\3\code_plate_detection_recognization\utils\utils.py
font = ImageFont.truetype(r".\3\code_plate_detection_recognization\data\SimHei.ttf",sizes, encoding="utf-8")
image=change_cv2_draw(img,label,(int(c1[0]), int(c1[1]) - 30),30,[225,225,225])##D:\code\aidlux_dd\3\code_plate_detection_recognization\detect_torch_pipeline.py
from utils.plots import colors##, plot_one_box
from utils.utils import plot_one_box
im0 = plot_one_box(xyxy, im0, label=label, color=colors(1, True), line_thickness=3)

测试图像:

cd code_plate_detection_recognization
python detect_torch_pipeline.py

3.4基于Aidlux平台的部署和推理测试

3.4.1车牌检测+识别模型的onnx序列化

export_yolov5.py

export_lprnet.py

同时用通过 detect_torch_pipeline.py 和detect_onnx_pipeline.py 运行同一张图片,结果显示如下:结果一致。

3.4.2车牌检测+识别模型的tflite的轻量化

修改对应的路径, 运行python export_tflite.py,完成车辆检测模型的tflite轻量化、车牌识别模型的tflite轻量化。

修改检测和识别的权重文件路径,以及输入图片路径和保存图片路径、运行 python detect_tflite_pipeline.py,输出结果图片。

3.4.3 车牌检测+识别的andorid端部署

修改对应的路径,在aidlux上运行:python aidlux/det_recog_aidlux_inference.py

手机端弹出图像检测页面,上面的显示中的中文显示乱码。

3.4.4中文字体修复

下载字体到代码相应位置,修改如下代码:

from PIL import Image,ImageDraw,ImageFont
def change_cv2_draw(image,strs,local,sizes,colour):cv2img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)pilimg = Image.fromarray(cv2img)draw = ImageDraw.Draw(pilimg)  # 图片上打印# font = ImageFont.truetype("./data/simhei.ttf",sizes, encoding="utf-8")font = ImageFont.truetype(r"/home/xly3dd/code_plate_detection_recognization/data/SimHei.ttf",sizes, encoding="utf-8")# draw.text((0,0),strs,colour,font=font)# font = ImageFont.truetype("simsun.ttc", 32, encoding="unic")# draw.text(local, strs, 'white', font=font)draw.text(local, strs, (128, 128, 128), font=font)image = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)return imagedef plot_one_box_class(x, img, label=None, predstr=None, color=None,  line_thickness=3):# Plots one bounding box on image imgtl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thicknesscolor = color or [np.random.randint(0, 255) for _ in range(3)]c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)if label:if predstr:tf = max(tl - 1, 1)  # font thicknesst_size = cv2.getTextSize(predstr, 0, fontScale=tl / 3, thickness=tf)[0]c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled# cv2.putText(img, predstr, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)image=change_cv2_draw(img,label,(int(c1[0]), int(c1[1]) - 30),30,[225,225,225])# return cv2.cvtColor(np.asarray(img), cv2.COLOR_BGR2RGB)return image

3.4.5视频测试展示

修改输入方式为视频:

# source ="/home/xly3dd/code_plate_detection_recognization/demo/images"
path = "/home/xly3dd/code_plate_detection_recognization/demo/videos/VID_20230305_171410.mp4"
capture = cvs.VideoCapture(path) # 获取视频
frame = capture.read()det_model_path = "/home/xly3dd/code_plate_detection_recognization/weights/yolov5.tflite"
recog_model_path = "/home/xly3dd/code_plate_detection_recognization/weights/LPRNet_Simplified.tflite"
save_dir = "/home/xly3dd/code_plate_detection_recognization/detect"index = 0
while True:frame = capture.read()index += 1if frame is None:breakprint(index)# image_ori = cv2.imread(os.path.join(source, img_name))image_ori = frame

测试显示:

测试视频:

20230306_020743

SVID_20230305_232642_1

参考链接

本文参考了Aidlux训练营中学习而来,详细代码可关注Aidlux公众号并回复关键词"智慧社区"获得。

其它同学的分享文章和心得也可在各技术网站搜索到。

基于AidLux平台实现智慧社区中高空抛物和车辆车牌识别相关推荐

  1. 基于Aidlux平台的智慧社区AI实战

    智慧社区作为智慧城市的最小单元,麻雀虽小五脏俱全.一般来说智慧社区主要分成以下三个方面:住房安全管控.社区环境管控以及物业服务管控三个部分. (1)住房安全管控,主要包括消防安全的监管和入侵安全之类. ...

  2. 基于Aidlux平台的智慧交通AI安全算法实战

    一. 通常来说,智慧交通行业主要是对交通场景内的行人,机动车,非机动车进行识别分析. 行人识别分析包括对行人的姿态,方向,外观,以及基于行人的交通事件识别分析,(行人闯红灯等). 机动车识别分析包括对 ...

  3. 基于AidLux平台和七牛云、喵提醒工具实现课室人头计数系统

    基于AidLux平台和七牛云.喵提醒工具实现课室人头计数系统 导读:说起人工智能,首先映入眼帘的,一定会是:1997年国际象棋机器"深蓝"战胜世界冠军卡斯帕罗夫和2016年围棋棋王 ...

  4. 基于android平台的手机游戏的设计与实现,基于Android平台手机游戏社区的设计与实现...

    摘要: 在移动终端性能的不断提高和移动互联网的不断普及,SNS社区以及不再只停留在电脑上,逐渐的走进了手机里,与以往的社区相比,手机社区有更好的实时性,以及能够更方便的提供LBS服务功能.目前每个社区 ...

  5. 基于智慧灯杆的智慧社区解决方案,看看智慧灯杆到底能做什么?

    来源:智能化弱电工程设计与施工 前言 大家好,我是薛哥.弱电行业最近两年比较火的一个方面,就是智慧灯杆,智慧灯杆不仅仅在道路上使用,也逐渐走入了小区里面,那么智慧灯杆在小区里面究竟能做什么呢?有什么解 ...

  6. 数字图像处理——大作业 基于车道信息的违法车辆车牌识别

    数字图像处理--大作业 基于车道信息的违法车辆车牌识别 一.车牌识别研究现状与分析 二.车牌识别算法原理 2.1 车牌定位 2.1.1 基于RGB阈值的车牌区域初定位 2.1.2 基于数学形态学的车牌 ...

  7. 澎思智慧社区解决方案:“人像+ReID行人再识别”算法融合机制开发新一代智慧社区平台 |百万人学AI评选

    2020 无疑是特殊的一年,而 AI 在开年的这场"战疫"中表现出了惊人的力量.站在"新十年"的起点上,CSDN[百万人学AI]评选活动正式启动.本届评选活动在 ...

  8. 基于AidLux平台的医院进出口人流量统计案例开发与测试

    1.环境配置 1.1.跨平台应用系统Aidlux AIdlux系统是基于ARM架构的跨生态(Android/鸿蒙+Linux)一站式AIOT应用开发平台.实际应用到现场的时候,通常会以几种形态:GPU ...

  9. 基于Aidlux平台的街道人流量统计开发与测试

    一.前言 目前我国智慧城市的场景划分覆盖面很广,比如智慧园区.智慧工地.智慧交通.智慧机场等等.不同的智慧场景,其覆盖范围都不一样,但通常而言,智慧城市行业主要是对空间内的人.车.物进行识别分析. 本 ...

最新文章

  1. 计算机网络拓扑结构 以下关于星型网络拓扑结构的描述正确的是______。 (多选题 )
  2. 建库、建表、建约束、插入测试数据
  3. boost::multiprecision模块实现安全素数的测试程序
  4. 记一次clickhouse查询问题Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = ‘deny‘)
  5. Go Web:HttpRouter路由(一)
  6. 您必须学习Java 8的函数式编程吗?
  7. ubuntu优化服务器网络连接数,ubuntu下解决高并发socket最大连接数限制,tcp默认1024个连接...
  8. 删过几十亿个账号,Facebook的人工智能是怎么培养出来的?
  9. HTML5新的解析顺序,HTML5新表单新功能解析
  10. Tensoflow-SSD代码解读(github-balancap代码)
  11. 还对Angel平台一知半解?腾讯专家为你指点迷津!
  12. 使用oligo软件包处理芯片数据
  13. 常见的两种解空间 全排列与幂集
  14. 开发3dMax插件的方法和应用
  15. 批量导出Outlook所有联系人到vcard文件
  16. webaudio ajax,Web Audio 入门之读取左右声道数据
  17. HashMap底层详讲
  18. 微软打算用DNA存储数据 但成本和速度仍是个大问题
  19. 【Codecs系列】MPEG4解码器可以解码H.263的码流吗?
  20. 银行定期存款产品目标客户的确定——基于逻辑回归

热门文章

  1. 尝鲜Idea最新UI,惊艳到了
  2. uni-app 边框线 app 上更粗的解决办法
  3. 大商创订单增加发票识别码编辑及显示功能
  4. 【控制】粒子群算法(PSO)优化滑模控制器参数
  5. android获取短信电话,Android:如何从收到的短信中获取电话号码?
  6. java毕业设计大型商场应急预案管理系统mybatis+源码+调试部署+系统+数据库+lw
  7. 1899:【17NOIP提高组】小凯的疑惑
  8. 王者争雄服务器维护,王者争雄新手攻略大全 王者争雄优先升级及玩法技巧分享...
  9. 74ls192加减无法正常工作
  10. ASP WEBSERVICER2005