【华为云-上云之路】【昇腾】【每天进步一点点】如何基于官方例程开发自己想实现的项目(Python版本)
前言
很多时候,基于各种需要,我们希望能在Atlas平台上开发自己想要的项目,虽然官方给出了很多例程项目,涉及分类、目标检测、分割等常用场景,但很多时候并不是我们想要的效果,可能需要更换输入方法,比如官方例程给的是摄像头输入,我们希望是本地视频输入等等问题,这个时候就需要自己去开发实现了,不过,做好是基于官方项目例程去实现,尽量不要从零开始,自己去开发,因为例程是经过专业工程师调试的,可以确保能在设备上运行起来,如果自己从头开发,可能会遇到很多工程师已经走过的坑,开发效率就比较低了。站在巨人的肩膀上,基于现成的案例去开发,避免重复造轮子。
开发案例
这里基于社区例程sample-classification-python(链接为https://gitee.com/Atlas200DK/sample-classification-python/tree/master)实现黑白图像上色,其实黑白图像上色这个项目是官方例程中的一个,记得以前有Python版本,现在好像找不到了,无所谓了,现在来试试吧。
1. 模型转换
可以说这是整个项目的核心部分了,首先要的到用于黑白图像上色的.om模型,这个可以参考案例找到模型,并按照要求转换https://gitee.com/Atlas200DK/sample-README/tree/master/sample-colorization。
2. 改造代码
首先,sample-classification-python比较简单,使用了一个模型,而且主要代码在classify.py中实现了,代码中明确指定了模型和输入图像的路径,我们只要相应修改就行了,把模型换为刚才转化的图像上色的模型,图像输入路径放上待上色的图片就行了,注意这里图片要是.jpg结尾的图片,因为在代码中是通过.jpg结尾来确定图片,并输入模型的,这要注意。
其次,就是模型输入尺寸大小了,这一点根据模型转换时设置的尺寸做修改。
最后,是后处理,这里很简单,直接写为图片就行了,但也因为如此,程序运行较慢,写图片比较费时间,而且使用OpenCV写的图片好像质量一般。
至此,大功告成。看看修改好的代码吧。
# coding=utf-8 import hiai import imageNetClasses import os import numpy as np import time import graph import post_process import cv2 cur_path = os.path.dirname(os.path.realpath(__file__)) os.chdir(cur_path) # resnet18OmFileName='./models/resnet18.om' resnet18OmFileName='./models/colorization.om' srcFileDir = './ImageNetRaw/' dstFileDir = './resnet18Result/' # 初始参数设定 resize_w = 224 resize_h = 224 out_w = 56 out_h = 56 def preprocess(img_bgr): bgr_img = img_bgr.astype(np.float32) orig_shape = bgr_img.shape[:2] bgr_img = bgr_img / 255.0 lab_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2Lab) orig_l = lab_img[:,:,0] if not orig_l.flags['C_CONTIGUOUS']: orig_l = np.ascontiguousarray(orig_l) lab_img = cv2.resize(lab_img, (resize_w, resize_h)).astype(np.float32) l_data = lab_img[:,:,0] if not l_data.flags['C_CONTIGUOUS']: l_data = np.ascontiguousarray(l_data) l_data = l_data - 50 return orig_shape, orig_l, l_data def postprocess(result_list, orig_shape, orig_l): result_array = result_list[0][0] ab_data = cv2.resize(result_array, orig_shape[::-1]) result_lab = np.concatenate((orig_l[:,:,np.newaxis],ab_data),axis=2) result_bgr = (255*np.clip(cv2.cvtColor(result_lab, cv2.COLOR_Lab2BGR),0,1)).astype('uint8') # file_name = os.path.join(output_path, 'out_'+pic) #cv.imwrite(file_name, result_bgr) # result_rgb = cv2.cvtColor(result_bgr, cv2.COLOR_RGB2BGR) # 转为RGB格式 result_rgb = result_bgr return result_rgb def Resnet18PostProcess(resultList, srcFilePath, dstFilePath, fileName, orig_shape, orig_l): if resultList is not None : # firstConfidence, firstClass = post_process.GenerateTopNClassifyResult(resultList, 1) # firstLabel = imageNetClasses.imageNet_classes[firstClass[0]] dstFileName = os.path.join(dstFilePath, fileName) # srcFileName = os.path.join(srcFilePath, fileName) # image = cv.imread(srcFileName) # txt = firstLabel + " " + str(round(firstConfidence[0]*100,2)) # cv.putText(image, txt, (15,20), cv.FONT_HERSHEY_COMPLEX_SMALL, 1.0, (0, 0, 255)) resultList[0] = resultList[0].reshape(1,2,56,56).transpose(0,2,3,1) img_rgb = postprocess(resultList, orig_shape, orig_l) cv2.imwrite(dstFileName, img_rgb) else : print('graph inference failed ') return None def main(): try: myGraph = graph.Graph(resnet18OmFileName) myGraph.CreateGraph() except Exception as e: print("Except:", e) return # dvppInWidth = 224 # dvppInHeight = 224 start = time.time() if not os.path.exists(dstFileDir): os.mkdir(dstFileDir) pathDir = os.listdir(srcFileDir) for allDir in pathDir: child = os.path.join(srcFileDir, allDir) img_bgr = cv2.imread(child) # input_image = cv2.resize(input_image, (dvppInWidth, dvppInHeight)) orig_shape, orig_l, l_data = preprocess(img_bgr) # 缩放为模型输入尺寸 resultList = myGraph.Inference(l_data) if resultList is None: print("graph inference failed") continue Resnet18PostProcess(resultList, srcFileDir, dstFileDir, allDir, orig_shape, orig_l) end = time.time() print('cost time '+str((end-start)*1000)+'ms') myGraph.Destroy() print('-------------------end') if __name__ == "__main__": main()
再来看看原来的代码
#coding=utf-8 import hiai import imageNetClasses import os import numpy as np import time import graph import post_process import cv2 as cv cur_path = os.path.dirname(os.path.realpath(__file__)) os.chdir(cur_path) resnet18OmFileName='./models/resnet18.om' srcFileDir = './ImageNetRaw/' dstFileDir = './resnet18Result/' def Resnet18PostProcess(resultList, srcFilePath, dstFilePath, fileName): if resultList is not None : firstConfidence, firstClass = post_process.GenerateTopNClassifyResult(resultList, 1) firstLabel = imageNetClasses.imageNet_classes[firstClass[0]] dstFileName = os.path.join(dstFilePath, fileName) srcFileName = os.path.join(srcFilePath, fileName) image = cv.imread(srcFileName) txt = firstLabel + " " + str(round(firstConfidence[0]*100,2)) cv.putText(image, txt, (15,20), cv.FONT_HERSHEY_COMPLEX_SMALL, 1.0, (0, 0, 255)) cv.imwrite(dstFileName, image) else : print('graph inference failed ') return None def main(): try: myGraph = graph.Graph(resnet18OmFileName) myGraph.CreateGraph() except Exception as e: print("Except:", e) return dvppInWidth = 224 dvppInHeight = 224 start = time.time() if not os.path.exists(dstFileDir): os.mkdir(dstFileDir) pathDir = os.listdir(srcFileDir) for allDir in pathDir: child = os.path.join(srcFileDir, allDir) input_image = cv.imread(child) input_image = cv.resize(input_image, (dvppInWidth, dvppInHeight)) resultList = myGraph.Inference(input_image) if resultList is None: print("graph inference failed") continue Resnet18PostProcess(resultList, srcFileDir, dstFileDir, allDir) end = time.time() print('cost time '+str((end-start)*1000)+'ms') myGraph.Destroy() print('-------------------end') if __name__ == "__main__": main()
对比可见,修改的还是比较少的。在官方例程上修改,还是比较轻松的,可以快速实现。当然,如果需要工业部署,可能要用C++开发了,C++比Python会难一些,所以最好在官方例程上修改,这样可以省下很多时间,提高开发效率。
下面看看运行结果
最终效果展示:
1. 素描
2. 近景
3. 人物
4. 自然风光
放大看细节,你会发现上色效果非常好,光线感自然,仿佛浑然天成,特别是右下角的森林,层次感非常好,仿佛流动的绿色海洋。这张图达到了1.33MB,未上色的原图是1.77MB,细节表现的很好。
最后,展示一段上色的老视频,原视频为一段航拍老北京的视频,通过视频可以看到上色效果并不是很好,这是因为原视频清晰度较差,分辨率低,特别是画面中物体边界不明显。一般情况下,对老视频上色,首先要做补帧和提高分辨率,或者称为超分辨技术,提升分辨率,使得画面景物边界明显,否则模糊的边界对上色影响很大。
最后,奉上全部代码(包括上述测试文件),下载解压后,拷贝到Atlas 200 DK上,运行classificationapp文件夹下的classify.py文件即可,即执行命令
python3 classify.py # Python2可能也行,没试过。
等待即可,即可得到前面的结果。注意时间有点长,可以先干点其他事情。
链接:https://pan.baidu.com/s/15lIpjBJ94-peq0-oB-PHXg
提取码:ocj3
- 点赞
- 收藏
- 关注作者
评论(0)