百度离线人脸识别sdk的使用

  • 1.1下载sdk运行
  • 1.2配置环境
  • 1.3 使用
    • 1.3.1 人脸图片检测方法
    • 1.3.2 人脸摄像头实时检测方法
    • 1.3.3 人脸注册方法
  • 1.4 打包

1.1下载sdk运行


1.2配置环境

添加至项目,可以拖动复制或者以类库形式添加
face-resource此文件夹 放到根目录上一层

激活文件与所有dll引用放到根目录
嫌麻烦可以将sdk的根目录所有文件直接拖动至项目的根目录

1.3 使用

百度离线人脸识别sdk只支持Release方式运行,所以项目的配置也改为此方式(不然会提示baiduapi…….一系列dll找不到
sdk使用OpenCvSharp3-AnyCPU的引用

  static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[UnmanagedFunctionPointer(CallingConvention.Cdecl)]delegate void FaceCallback(IntPtr bytes, int size, String res);// sdk初始化[DllImport("BaiduFaceApi.dll", EntryPoint = "sdk_init", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]private static extern int sdk_init(bool id_card);// 是否授权[DllImport("BaiduFaceApi.dll", EntryPoint = "is_auth", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]private static extern bool is_auth();// 获取设备指纹[DllImport("BaiduFaceApi.dll", EntryPoint = "get_device_id", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]private static extern IntPtr get_device_id();// sdk销毁[DllImport("BaiduFaceApi.dll", EntryPoint = "sdk_destroy", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]private static extern void sdk_destroy();// 测试获取设备指纹device_idpublic static void test_get_device_id(){IntPtr ptr = get_device_id();string buf = Marshal.PtrToStringAnsi(ptr);Console.WriteLine("device id is:" + buf);}[STAThread]static void Main(){bool id = false;int n = sdk_init(id);if (n != 0){Console.WriteLine("auth result is {0:D}", n);Console.ReadLine();}// 测试是否授权bool authed = is_auth();Console.WriteLine("authed res is:" + authed);test_get_device_id();Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}}

使用时将Program类修改,不然无法使用人脸检测接口 错误报告为参数非法回传 -1

1.3.1 人脸图片检测方法

[DllImport("BaiduFaceApi.dll", EntryPoint = "track", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]private static extern IntPtr track(string file_name, int max_track_num);public void test_track(){// 传入图片文件绝对路径string file_name = "d:\\kehu2.jpg";int max_track_num = 1; // 设置最多检测人数(多人脸检测),默认为1,最多可设为10IntPtr ptr = track(file_name, max_track_num);string buf = Marshal.PtrToStringAnsi(ptr);Console.WriteLine("track res is:" + buf);}

人脸检测接口,此方法需要在d盘根目录放一张名为“kehu2.jpg”的图片来检测是否含有人脸。

1.3.2 人脸摄像头实时检测方法

public void usb_csharp_track_face(int dev){using (var window = new Window("face"))using (VideoCapture cap = VideoCapture.FromCamera(dev)){if (!cap.IsOpened()){Console.WriteLine("open camera error");return;}// Frame image bufferMat image = new Mat();// When the movie playback reaches end, Mat.data becomes NULL.while (true){RotatedRect box;                                       cap.Read(image); // same as cvQueryFrameif (!image.Empty()){int ilen = 2;//传入的人脸数TrackFaceInfo[] track_info = new TrackFaceInfo[ilen];for (int i = 0; i < ilen; i++){track_info[i] = new TrackFaceInfo();track_info[i].landmarks = new int[144];track_info[i].headPose = new float[3];track_info[i].face_id = 0;track_info[i].score = 0;}int sizeTrack = Marshal.SizeOf(typeof(TrackFaceInfo));IntPtr ptT = Marshal.AllocHGlobal(sizeTrack* ilen);//Marshal.Copy(ptTrack, 0, ptT, ilen);//                        FaceInfo[] face_info = new FaceInfo[ilen];//                        face_info = new FaceInfo(0.0F,0.0F,0.0F,0.0F,0.0F);//Cv2.ImWrite("usb_track_Cv2.jpg", image);/*  trackMat*  传入参数: maxTrackObjNum:检测到的最大人脸数,传入外部分配人脸数,需要分配对应的内存大小。*            传出检测到的最大人脸数*    返回值: 传入的人脸数 和 检测到的人脸数 中的最小值,实际返回的人脸。****/int faceSize = ilen;//返回人脸数  分配人脸数和检测到人脸数的最小值int curSize = ilen;//当前人脸数 输入分配的人脸数,输出实际检测到的人脸数faceSize = track_mat(ptT, image.CvPtr, ref curSize);for (int index = 0; index < faceSize; index++){IntPtr ptr = new IntPtr();if( 8 == IntPtr.Size){ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);}else if(4 == IntPtr.Size){ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);}track_info[index] = (TrackFaceInfo)Marshal.PtrToStructure(ptr, typeof(TrackFaceInfo));//face_info[index] = (FaceInfo)Marshal.PtrToStructure(info_ptr, typeof(FaceInfo));Console.WriteLine("in Liveness::usb_track face_id is {0}:",track_info[index].face_id);Console.WriteLine("in Liveness::usb_track landmarks is:");for (int k = 0; k < 1; k ++){Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},", track_info[index].landmarks[k], track_info[index].landmarks[k+1],track_info[index].landmarks[k+2], track_info[index].landmarks[k + 3],track_info[index].landmarks[k+4], track_info[index].landmarks[k + 5],track_info[index].landmarks[k+6], track_info[index].landmarks[k + 7],track_info[index].landmarks[k+8], track_info[index].landmarks[k + 9]);}for (int k = 0; k < track_info[index].headPose.Length; k++){Console.WriteLine("in Liveness::usb_track angle is:{0:f}", track_info[index].headPose[k]);}Console.WriteLine("in Liveness::usb_track score is:{0:f}", track_info[index].score);// 角度Console.WriteLine("in Liveness::usb_track mAngle is:{0:f}", track_info[index].box.mAngle);// 人脸宽度Console.WriteLine("in Liveness::usb_track mWidth is:{0:f}", track_info[index].box.mWidth);// 中心点X,Y坐标Console.WriteLine("in Liveness::usb_track mCenter_x is:{0:f}", track_info[index].box.mCenter_x);Console.WriteLine("in Liveness::usb_track mCenter_y is:{0:f}", track_info[index].box.mCenter_y); 画人脸框box = bounding_box(track_info[index].landmarks, track_info[index].landmarks.Length);draw_rotated_box(ref image, ref box, new Scalar(0, 255, 0));// 实时检测人脸属性和质量可能会视频卡顿,若一定必要可考虑跳帧检测// 获取人脸属性(通过传入人脸信息)//IntPtr ptrAttr = FaceAttr.face_attr_by_face(image.CvPtr, ref track_info[index]);//string buf = Marshal.PtrToStringAnsi(ptrAttr);//Console.WriteLine("attr res is:" + buf); 获取人脸质量(通过传入人脸信息)//IntPtr ptrQua = FaceQuality.face_quality_by_face(image.CvPtr, ref track_info[index]);//buf = Marshal.PtrToStringAnsi(ptrQua);//Console.WriteLine("quality res is:" + buf); 实时检测人脸特征值可能会视频卡顿,若一定必要可考虑跳帧检测//float[] feature = new float[512];//IntPtr ptrfea = new IntPtr();//int count = FaceCompare.get_face_feature_by_face(image.CvPtr, ref track_info[index], ref ptrfea); 返回值为512表示取到了特征值//if(ptrfea == IntPtr.Zero)//{//    Console.WriteLine("Get feature failed!");//    continue;//}//if (count == 512)//{//    for (int i = 0; i < count; i++)//    {//        IntPtr floptr = new IntPtr();//        if ( 8 == IntPtr.Size)//        {//            floptr = (IntPtr)(ptrfea.ToInt64() + i * count * Marshal.SizeOf(typeof(float)));//        }//        else if( 4 == IntPtr.Size)//        {//            floptr = (IntPtr)(ptrfea.ToInt32() + i * count * Marshal.SizeOf(typeof(float)));//        }//        feature[i] = (float)Marshal.PtrToStructure(floptr, typeof(float));//        Console.WriteLine("feature {0} is: {1:e8}", i, feature[i]);//    }//    Console.WriteLine("feature count is:{0}", count);//}}Marshal.FreeHGlobal(ptT);window.ShowImage(image);Cv2.WaitKey(1);Console.WriteLine("mat not empty");}else{Console.WriteLine("mat is empty");}}image.Release();}}

以上为原sdk方法;
只可检测人脸 不可活体检测;

  static VideoCapture camera1 = null;static VideoCapture camera2 = null;public bool usb_csharp_track_face(int dev){string buf = "";int faceSize = 0;int faceNum = 2;//传入的人脸数int face_size = faceNum;//当前传入人脸数,传出人脸数//VideoCapture cap = VideoCapture.FromCamera(dev);//Mat image = new Mat();long ir_time = 0;// 序号0为电脑识别的usb摄像头编号,本demo中0为ir红外摄像头// 不同摄像头和电脑识别可能有区别// 编号一般从0-10 */            int device = select_usb_device_id();camera1 = VideoCapture.FromCamera(device);if (!camera1.IsOpened()){Console.WriteLine("camera1 open error");return false;}camera1.Set(CaptureProperty.FrameWidth, 1440);camera1.Set(CaptureProperty.FrameHeight, 1080);camera2 = VideoCapture.FromCamera(device + 1);if (!camera2.IsOpened()){Console.WriteLine("camera2 open error");return false;}RotatedRect box;Mat frame1 = new Mat();Mat frame2 = new Mat();Mat rgb_mat = new Mat();Mat ir_mat = new Mat();//var window_ir = new Window("ir_face");//var window_rgb = new Window("rgb_face");if (!camera1.IsOpened()){return false;}#region 尝试while (true){//Thread.Sleep(1000);camera1.Read(frame1);camera2.Read(frame2);if (!frame1.Empty() && !frame2.Empty()){int ilen = 2;//传入的人脸数TrackFaceInfo[] track_info = new TrackFaceInfo[ilen];for (int i = 0; i < ilen; i++){track_info[i] = new TrackFaceInfo();track_info[i].landmarks = new int[144];track_info[i].headPose = new float[3];track_info[i].face_id = 0;track_info[i].score = 0;}int sizeTrack = Marshal.SizeOf(typeof(TrackFaceInfo));IntPtr ptT = Marshal.AllocHGlobal(sizeTrack * ilen);#region 原if (frame1.Size(0) > frame2.Size(0)){rgb_mat = frame1;ir_mat = frame2;}else{rgb_mat = frame2;ir_mat = frame1;}#endregionfloat rgb_score = 0;float ir_score = 0;//Marshal.Copy(ptTrack, 0, ptT, ilen);//FaceInfo[] face_info = new FaceInfo[ilen];//face_info = new FaceInfo(0.0F,0.0F,0.0F,0.0F,0.0F);//Cv2.ImWrite("usb_track_Cv2.jpg", image);/*  trackMat*  传入参数: maxTrackObjNum:检测到的最大人脸数,传入外部分配人脸数,需要分配对应的内存大小。*            传出检测到的最大人脸数*    返回值: 传入的人脸数 和 检测到的人脸数 中的最小值,实际返回的人脸。****/faceSize = ilen;//返回人脸数  分配人脸数和检测到人脸数的最小值int curSize = ilen;//当前人脸数 输入分配的人脸数,输出实际检测到的人脸数faceSize = track_mat(ptT, frame1.CvPtr, ref curSize);IntPtr ptr1 = rgb_ir_liveness_check_faceinfo(rgb_mat.CvPtr, ir_mat.CvPtr, ref rgb_score, ref ir_score, ref faceSize, ref ir_time, ptT);curSize = ilen;faceSize = track_mat(ptT, frame1.CvPtr, ref curSize);//Console.WriteLine(rgb_score.ToString());//Console.WriteLine(ir_score.ToString());//textBox1.Text = faceSize.ToString();for (int index = 0; index < faceSize; index++){IntPtr ptr = new IntPtr();if (8 == IntPtr.Size){ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);}else if (4 == IntPtr.Size){ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);}track_info[index] = (TrackFaceInfo)Marshal.PtrToStructure(ptr, typeof(TrackFaceInfo));IntPtr ptrQua = FaceQuality.face_quality_by_face(frame1.CvPtr, ref track_info[index]);buf = Marshal.PtrToStringAnsi(ptrQua);}textBox2.Text = buf.ToString();Marshal.FreeHGlobal(ptT);//window.ShowImage(image);pictureBox1.Image = frame1.ToBitmap();Cv2.WaitKey(1);#region 测试if (rgb_score != 0 && ir_score != 0){if (faceSize >= 1){JObject jObject = (JObject)JsonConvert.DeserializeObject(buf);var json = (JObject)JsonConvert.DeserializeObject(jObject["data"].ToString());string result = json["result"].ToString();// textBox1.Text = json["result"].ToString();var json1 = (JObject)JsonConvert.DeserializeObject(result);if (double.Parse(json1["bluriness"].ToString()) <= 0.00001 && double.Parse(json1["occl_r_eye"].ToString()) < 0.1 && double.Parse(json1["occl_l_eye"].ToString()) < 0.1 &&double.Parse(json1["occl_mouth"].ToString()) <= 0 && double.Parse(json1["occl_nose"].ToString()) < 0.11 && double.Parse(json1["occl_r_contour"].ToString()) < 0.1&& double.Parse(json1["occl_chin"].ToString()) <= 0 && double.Parse(json1["occl_l_contour"].ToString()) < 0.1){string fileName = DateTime.Now.ToString("yyyyMMdd") + ".jpg";string path = AppDomain.CurrentDomain.BaseDirectory;string picture = path + @"img" + "\\" + fileName;frame1.SaveImage(picture);falnem = picture;if (Sdistinguish() != "0"){Class1 c = new Class1();Thread.Sleep(2000);dtTo = new TimeSpan(0, 0, 2);camera2.Release();camera2.Release();thread.Abort();return true;}else{Thread.Sleep(2000);dtTo = new TimeSpan(0, 0, 2);camera2.Release();camera2.Release();thread.Abort();//msg2 msg2 = new msg2();//msg2.Show();return true;this.Close();}Thread.Sleep(2000);thread.Abort();//msg2 msg2 = new msg2();//msg2.Show();this.Close();//window.Close();}}}#endregion//return faceSize;}else{Console.WriteLine("mat is empty");}}#endregionframe1.Release();return false;//usb_csharp_track_face(1);}

以上为我修改后的;

  private string distinguish(){dz = "1";//string fileName = DateTime.Now.ToString("yyyyMMddHH") + ".jpg";string fileName = falnem;//string fileName = "" + ".jpg";//SavePicture(fileName);FaceCompare faceCompare = new FaceCompare();JObject jObject = (JObject)JsonConvert.DeserializeObject(faceCompare.test_identify(fileName, "group", ""));//  JObject jObject = (JObject)JsonConvert.DeserializeObject(faceCompare.test_identify("d:\\4.jpg", "test_group", "u1"));var json = (JObject)JsonConvert.DeserializeObject(jObject["data"].ToString());var json1 = (JObject)JsonConvert.DeserializeObject(json["result"].ToString()); var json1 = (JArray)json["result"].ToString(); textBox1.Text = "对比值:" + json1["score"].ToString() +"/r用户:"+json1["user_id"].ToString() ;textBox1.Text= faceCompare.test_identify("d:\\4.jpg", "test_group", "test_user");string result = json["result"].ToString().Substring(1, json["result"].ToString().Length - 2);// textBox1.Text = json["result"].ToString();var json1 = (JObject)JsonConvert.DeserializeObject(result);//textBox2.Text = "对比值:" + json1["score"].ToString() + "\r\n用户:" + json1["user_id"].ToString();string user = json1["user_id"].ToString();string lockes = "0";#region 查询数据库using (var db = new ces(dbPath)){//List<TestFaceDB> testFaces = db.testFaces.Where(x => x.User == json1["user_id"].ToString()).ToList();var testFaces = db.testFaces.Where(x => x.User == user).ToList();//string testFaces = db.testFaces.Select(*).Where(x => x.User == json1["user_id"].ToString()).ToString();//this.Text = $"{DateTime.Now}, 查到{books.Count}条记录";lockes = testFaces[0].Locks;}int lo = int.Parse(lockes);if (int.Parse(lockes) > 100){int d = 0;while (lo > 100){lo -= 100;d++;}int z = 1;for (int i = 0; i < d - 1; i++){z = z * 2;};dz = "0" + z.ToString();}#endregiondouble score = double.Parse(json1["score"].ToString());lockes = lo.ToString();if (score > 80){if (int.Parse(lockes) < 10) lockes = "0" + lockes;return lockes;}else{return lockes;}}
//1:N比较
public /*void*/string test_identify(string str, string usr_grp, string usr_id){string file1 = str;//"d:\\6.jpg";string user_group = usr_grp;//"test_group";string user_id = usr_id;//"test_user";IntPtr ptr = identify(file1, user_group, user_id);string buf = Marshal.PtrToStringAnsi(ptr);//Console.WriteLine("identify res is:" + buf);return buf;}

distinguish()方法为识别后在数据库中寻找匹配人脸数据;
将活体实时检测与人脸实时检测合并为一个方法,关闭了window显示窗口,修改为pictureBox控件 通过线程调用(不然死循环会崩溃);关闭摄像头为 Release();方法

数据均为json数据 ;
具体数据参数见百度文档
根据需求修改判断条件是否符合项目中的人脸标准;
识别流程为
启动线程->打开摄像头->检测到人脸->将人脸图片保存->用图片传入调用人脸对比方法;

1.3.3 人脸注册方法

string user_id = User.Text;string group_id = "group";string file_name = falnem;string lockse = group.Text;string user_info = info.Text;string zc =  faceManager.test_user_add(user_id, group_id, file_name, user_info);JObject jObjectzc = (JObject)JsonConvert.DeserializeObject(zc);if(jObjectzc["msg"].ToString()== "success"){List<TestFaceDB> testFaceDBs  = new List<TestFaceDB>(){new TestFaceDB()  {User = user_id,Locks = lockse,Phone = user_info}};textBox1.Text = dbPath;using (var db = new ces(dbPath)){int count = db.InsertAll(testFaceDBs);//this.Text = $"{DateTime.Now}, 插入{count}条记录";}msg msg = new msg();msg.ShowDialog();Thread.Sleep(5000);dtTo = new TimeSpan(0, 0, 2);camera1.Release();camera2.Release();return true;}Thread.Sleep(3000);

同上的方法 先检测摄像头中是否使活体人脸并存图片文件,保存后调用人脸注册

public /*void*/ string test_user_add(string uid,string gid,string fil,string uin){//人脸注册//string user_id = "test_user";//string group_id = "test_group";//string file_name = "d:\\2.jpg";//string user_info = "user_info";string user_id = uid;string group_id = gid;string file_name = fil;string user_info = uin;IntPtr ptr = user_add(user_id, group_id, file_name, user_info);string buf = Marshal.PtrToStringAnsi(ptr);return buf;}

这个我修改添加了参数;

因sdk带的SQLite数据库字段比较少,并且我也没有花心思想办法去修改它创建的数据库,所以创建个新的和sdk中数据库以一个字段相连,就当扩展数据库了;
在注册的时候顺带存新数据库一份就可以,要什么字段看自己需求;
当查找数据库中数据的时候查到就取那个字段,然后去新数据库中查找对应的其他字段。

1.4 打包


打包简单方法直接将根目录数据放到一个文件夹然后添加到Application Folder文件夹,然后在同目录将face-resource放进去就可以了,在安装的时候不能安装到系统盘 不然接口会出问题;不知道什么原因
安装到一个电脑的时候需要使用百度离线识别的sdk序列号激活不然不可使用;因为百度离线人脸识别sdk 是通过电脑指纹判断是否激活,如果遇到LicenseTool.exe打不开弹出缺少系统dll组件请去网络下载,或许因为电脑系统为盗版系统组件未安装齐
也可以在百度下载激活的压缩文件;
在添加输出的时候将sdk作为本地化资源输出,项目作为主输出,输出类型为Release;

百度离线人脸识别sdk的使用相关推荐

  1. 百度离线人脸识别SDK

    1,采坑备忘 (1)8.1版本的SDK在spring-boot接口访问第一次正常,第二次之后JVM会奔溃,可能是java gc 处理C++开出的内存有问题. 换6.1.3版本的SDK. java+Wi ...

  2. flutter集成百度离线人脸识别

    flutter集成百度离线人脸识别 概述 最近公司项目有人脸认证.活体检测的需求,原声的不要拿手,只能翻阅各位大佬的轮子:最终尝试出来百度的离线活体检测方案可用. 第一步 flutter_bdface ...

  3. java 基于虹软离线人脸识别SDK 2.0 最新版

    虹软人脸识别SDK之Java版,支持SDK 1.1+,以及当前最新版本2.0,滴滴,抓紧上车! JDK SDK Win release license status 前言 由于业务需求,最近跟人脸识别 ...

  4. 调用百度的人脸识别SDK实现人脸检测

    在百度控制台创建APP具体操作过程看上一篇文章https://blog.csdn.net/qq_34613314/article/details/117290951?spm=1001.2014.300 ...

  5. Unity —— 百度人脸识别SDK使用

    又到了交完项目暂时么有事情的时候啦~ 然后自己无聊,突然想研究研究人脸识别 =- = 于是就开始了 零. 先在网上查Unity 人脸识别 ,你会发现网上的大部分都是 OpenCV 和 BaiduAI ...

  6. 虹软人脸识别SDK接入Milvus实现海量人脸快速检索

    虹软人脸识别SDK接入Milvus实现海量人脸快速检索 背景 虹软SDK及Milvus简介 开发环境 虹软人脸识别SDK使用简介 Milvus环境搭建 快速检索实现 人脸识别流程简介 快速检索 虹软S ...

  7. SpringBoot整合百度人脸识别SDK离线版操作步骤,Windows发布打包SpringBoot百度人脸识别SDK项目,以及解决百度人脸识别SDK离线版遇到的问题

    前言 1.下载百度人脸识别SDK离线版. 2.开发工具:IntelliJ IDEA 百度人脸识别官网:https://cloud.baidu.com/doc/FACE/s/Ol0rre5u5 步骤 一 ...

  8. 安卓 sdk 离线包_百度离线ocr识别开发sdk包

    百度离线ocr识别开发sdk包 文字识别是人工智能里面比较常见的一个功能,以前社会需要专门的打字员把图片或者书本上的内容,输入计算机上,现在有文字识别OCR很简单就可以实现,图片.截图.纸质文档等等都 ...

  9. 百度人脸识别SDK的坑

    百度人脸识别SDK jar包冲突: 首先是百度人脸识别的SDK的Maven依赖: com.baidu.aip java-sdk 4.11.3 <dependency><groupId ...

  10. android Camera2 API适配百度人脸识别SDK

    Camera2 API替换Camera API之后的问题 camera和camera2的最主要区别之一就是camera2不再支持nv21的输出,通常我们为了使视频预览更加的流畅,会采用YUV_420_ ...

最新文章

  1. Microbiome:宏基因组揭示冻土带、温带草原和热带土壤抗性的特征
  2. C语言中 指针强化训练之 memcpy
  3. 寄娱于学第2天——PHP骰子游戏篇--优化
  4. cstring查找子字符串_动态规划6:两个字符串的最长连续公共子串
  5. 6、ShardingSphere 之 读写分离
  6. VTK:PolyData之ImplicitDataSetClipping
  7. Sentinel(十二)之实时监控
  8. Java PushbackInputStream markSupported()方法与示例
  9. python的empty函数_python中numpy.empty()函数的用法
  10. python requests 乱码_python3 requests 抓取乱码问题
  11. 如何让百度快速收录自己的wordpress网站
  12. 扩散模型 (Diffusion Model) 简要介绍与源码分析
  13. 开源微服务框架 汇总
  14. Link16通信战术数据链分析与MATLAB仿真程序
  15. 计算机数学英语基础,2020考研计算机数学复习四大基本方向
  16. 手把手教你如何架设一个属于自己的Discuz论坛---------详细过程-----简单易懂------速看!!!!
  17. python海龟绘图代码大全-Python中的高级turtle(海龟)作图
  18. 毛球修剪器方案开发的工作原理和构成
  19. 放弃51单片机直接学32是因为51难找工作?
  20. 即刻监听搜索输入框并请求数据

热门文章

  1. 程序员如何在工作之外获得收入
  2. 删除下拉框只找23火星软件_下拉怎么做首选23火星软件
  3. 用ESP32打造一个物联网红外测温打卡机/春节结束急着上班?哒咩,再努力奋斗也要先测体温
  4. 不同角度的5S管理作用总结
  5. 遇到问题--java--mac版本的idea在控制台中使用mvn命令not found
  6. 关于es cpu安装黑苹果,并实现变频
  7. canvas系列 — canvas常用API介绍
  8. ImageAI:几行代码跑深度学习
  9. 嵌入式状态机编程-QP状态机框架与常见状态机方法
  10. 【我的Android进阶之旅】APK反编译教程和工具下载