查看: 2600|回复: 0

角蜂鸟实例教程 > Android > 手绘识别

[复制链接]

该用户从未签到

发表于 2018-8-8 15:40:32 | 显示全部楼层 |阅读模式
分享到:
本帖最后由 cll826 于 2018-8-7 15:05 编辑

手绘识别

本文主要给大家介绍下在Android平台下使用角蜂鸟实现手绘识别功能

准备工作

  • 配置环境等详情请参照Hello 2018里的快速开始,此处不具体阐述
  • 下载物体检测所需模型graph_sg文件,在您Android Studio中,当前module下新建assets包,将下载的模型文件复制到该目录下
  • 因工程需要处理图像,所以使用了javacv库,可从GitHub自行下载或点击链接从示例工程中libs下拷贝到自己工程
  • 将class_list_chn.txt文件拷贝到Android设备的存储空间下,用于345种物体的比对

具体实现

  • 将graph文件传输到角蜂鸟里

  1. int status = allocateGraphByAssets("graph_sg");
复制代码
  • 读取物体分类文件
  1. try {
  2. BufferedReader bufferedReader = new BufferedReader(new FileReader(Environment.getExternalStorageDirectory().getAbsolutePath() + "/hs/class_list_chn.txt"));
  3. for (int i = 0; i < 345; i++) {
  4. String line = bufferedReader.readLine();
  5. if (line != null) {
  6. String[] strings = line.split(" ");
  7. mObjectNames[i] = strings[0];
  8. }
  9. }
  10. bufferedReader.close();
  11. } catch (FileNotFoundException e) {
  12. e.printStackTrace();
  13. Log.e("SketchGuessThread", "FileNotFoundException");
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. Log.e("SketchGuessThread", "IOException");
  17. }
复制代码
  • 获取角蜂鸟内置的摄像头图像
  1. byte[] bytes = deviceGetImage();
复制代码

注意:开发者也可以根据自己需求选择自己外部摄像头数据。

  • 处理图像,并将处理好的tensor传给角蜂鸟

  1. opencv_core.IplImage bgrImage = opencv_core.IplImage.create(FRAME_W, FRAME_H, opencv_core.IPL_DEPTH_8U, 3);
  2. bgrImage.getByteBuffer().put(bytes_frame);
  3. int sg_weight = (int) (FRAME_W * roi_ratio);
  4. //crop
  5. opencv_core.CvRect cvRect = opencv_core.cvRect((int) (FRAME_W * (0.5 - roi_ratio / 2)), (int) (FRAME_H * 0.5 - sg_weight / 2), sg_weight, sg_weight);
  6. cvSetImageROI(bgrImage, cvRect);
  7. opencv_core.IplImage cropped = cvCreateImage(cvGetSize(bgrImage), bgrImage.depth(), bgrImage.nChannels());
  8. cvCopy(bgrImage, cropped);
  9. //canny
  10. opencv_core.IplImage image_canny = opencv_core.IplImage.create(sg_weight, sg_weight, opencv_core.IPL_DEPTH_8U, 1);
  11. cvCanny(cropped, image_canny, 120, 45);
  12. //dilate
  13. opencv_core.IplImage image_dilate = opencv_core.IplImage.create(sg_weight, sg_weight, opencv_core.IPL_DEPTH_8U, 1);
  14. //kernel = np.ones((4,4),np.uint8)
  15. opencv_core.IplConvKernel iplConvKernel = cvCreateStructuringElementEx(4, 4, 0, 0, CV_SHAPE_RECT);
  16. cvDilate(image_canny, image_dilate, iplConvKernel, 1);
  17. opencv_core.IplImage image_dilate_rgba = opencv_core.IplImage.create(sg_weight, sg_weight, opencv_core.IPL_DEPTH_8U, 4);
  18. cvCvtColor(image_dilate, image_dilate_rgba, CV_GRAY2RGBA);
  19. //resize
  20. opencv_core.IplImage image_load = opencv_core.IplImage.create(28, 28, opencv_core.IPL_DEPTH_8U, 4);
  21. cvResize(image_dilate_rgba, image_load);
  22. //把该image_dilate转化成float类型传送给角蜂鸟
  23. Bitmap bitmap_tensor = IplImageToBitmap(image_load);
  24. Message message1 = new Message();
  25. message1.arg1 = 2;
  26. message1.obj = bitmap_tensor;
  27. mHandler.sendMessage(message1);
  28. int[] pixels = new int[28 * 28];
  29. bitmap_tensor.getPixels(pixels, 0, 28, 0, 0, 28, 28);
  30. float[] floats = new float[28 * 28 * 3];
  31. for (int i = 0; i < 28 * 28; i++) {
  32. floats[i] = Color.red(pixels[i]) * 0.007843f - 1;
  33. floats[3 * i + 1] = Color.green(pixels[i]) * 0.007843f - 1;
  34. floats[3 * i + 2] = Color.blue(pixels[i]) * 0.007843f - 1;
  35. }
  36. int status_tensor = loadTensor(floats, floats.length, 0);
复制代码
  • 获取返回的处理结果
  1. float[] result = mHsApi.getResult(0);
复制代码
  • 处理result返回值,排列取出最大的5个数对应的idex.
  1. public String[] sortMax5(float[] result) {

  2.    HashMap<Integer, Float> integerFloatHashMap = new HashMap<>();
  3.    String[] object_names = new String[5];
  4.    for (int i = 0; i < result.length; i++) {
  5.        integerFloatHashMap.put(i, result[i]);
  6.    }
  7.    Arrays.sort(result);
  8.    for (int i = 0; i < result.length; i++) {
  9.        if (integerFloatHashMap.get(i) == result[result.length - 1]) {
  10.            object_names[0] = mObjectNames[i] + " " + result[result.length - 1];
  11.        }
  12.        if (integerFloatHashMap.get(i) == result[result.length - 2]) {
  13.            object_names[1] = mObjectNames[i] + " " + result[result.length - 2];
  14.        }
  15.        if (integerFloatHashMap.get(i) == result[result.length - 3]) {
  16.            object_names[2] = mObjectNames[i] + " " + result[result.length - 3];
  17.        }
  18.        if (integerFloatHashMap.get(i) == result[result.length - 4]) {
  19.            object_names[3] = mObjectNames[i] + " " + result[result.length - 4];
  20.        }
  21.        if (integerFloatHashMap.get(i) == result[result.length - 5]) {
  22.            object_names[4] = mObjectNames[i] + " " + result[result.length - 5];
  23.        }
  24.    }
  25.    return object_names;
  26. }
复制代码
  • 结果显示在view上,效果如图:

图片.jpeg


友好提醒:因Android设备基本都是USB2.0,所以不建议使用1080P的图像,传输比较耗时,会有卡顿感,可以使用360P的图像,铺满屏幕即可

具体代码可去GitHub下载,地址如下 SungemSDK-AndroidExamples


回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

手机版|小黑屋|与非网

GMT+8, 2024-11-20 00:45 , Processed in 0.118968 second(s), 16 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.