谁家没几张有魔力的老照片,虽然背景简单、pose不经设计,但有了几十年时间发酵,也成了一段父母长辈们年轻岁月的故事,意义非凡。本周末父亲节报到,我厂程序员阿强苦思冥想,如何给老爸带来不同的节日礼物?环顾四周,桌上一个旧相册激发了他的灵感。陈旧泛黄的照片,封藏了老爸年轻时意气风发的模样,为什么不用本身的技术,让老爸重现往日时光呢?想到作到!他旋即就对老爸珍藏的旧照下了一番功夫,运用机器学习图像超分辨率,将那些斑驳模糊、褶皱破损的老照片,一键高清,效果惊艳老爸!java
效果示例
图像超分辨率
图像超分辨率即将低分辨率、成像模糊的图片恢复到高分辨率,提高图像像素密度,还原更多原图场景成像细节。android
图像超分辨率在计算机视觉领域拥有普遍应用需求,助力高效提高图像模式识别能力和图像分析效果。日渐精进的图像超分辨率技术也在咱们的生活工做中扮演愈来愈重要的角色,小到一张我的模糊旧照的清晰化处理,大到医疗图像诊断、安防监控、甚至是卫星成像等领域的诸多运用。git
华为机器学习-图像超分辨率提供了1x和3x的超分能力。1x超分去除压缩噪声,3x超分不只有效抑制压缩噪声,并且提供3倍的放大能力。支持通用场景超分(绿植、美食、工卡等),如提高网络上低质图片画质,在阅读新闻时获取更清晰大图等。程序员
开发准备
Maven仓和SDK的配置步骤能够参考开发者网站中的应用开发介绍:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/imagesuper-resolution-sdk-0000001052064928-V5?ha_source=hms1github
配置集成的SDK包网络
在应用的build.gradle文件中,dependencies内添加图像超分的SDK依赖app
implementation'com.huawei.hms:ml-computer-vision-imagesuperresolution:2.0.4.300' implementation'com.huawei.hms:ml-computer-vision-imagesuperresolution-model:2.0.4.300'
配置AndroidManifest.xml 机器学习
打开main文件夹中的AndroidManifest.xml文件,能够根据场景和使用须要,配置读取和写入手机存储的权限,在<application>前添加异步
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在<application>内添加以下语句,当应用安装后,会自动更新最新的机器学习模型到设备async
<meta-data android:name="com.huawei.hms.ml.DEPENDENCY" android:value= "imagesuperresolution"/>
详细开发步骤
配置存储权限申请
在MainActivity的onCreate()方法中,首先对手机存储的读取权限进行判断,若是未获取权限,则经过requestPermissions进行申请,若是已经获取了,则调用的startSuperResolutionActivity()方法,进行图像超分操做
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE); } else { startSuperResolutionActivity(); }
检查权限申请的结果
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { startSuperResolutionActivity(); } else { Toast.makeText(this, "Permission application failed, you denied the permission", Toast.LENGTH_SHORT).show(); } } }
权限申请完毕以后,建立Button,并配置点击Button后对存储内的图片进行读取
private void selectLocalImage() { Intent intent = new Intent(Intent.ACTION_PICK, null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(intent, REQUEST_SELECT_IMAGE); }
配置图像超分辨率分析器
在进行图像超分处理以前,要建立并配置图像超分辨率分析器,本例中配置了1x和3x两种超分参数,经过selectItem的不一样取值进行对应的选择
private MLImageSuperResolutionAnalyzer createAnalyzer() { if (selectItem == INDEX_1X) { return MLImageSuperResolutionAnalyzerFactory.getInstance().getImageSuperResolutionAnalyzer(); } else { MLImageSuperResolutionAnalyzerSetting setting = new MLImageSuperResolutionAnalyzerSetting.Factory() .setScale(MLImageSuperResolutionAnalyzerSetting.ISR_SCALE_3X) .create(); return MLImageSuperResolutionAnalyzerFactory.getInstance().getImageSuperResolutionAnalyzer(setting); } }
构造并处理图像
在对图像进行超分处理以前,须要将其转换为ARGB8888类型的Bitmap格式,再建立为MLFrame。首先在添加图片后,获取图片的相关信息,覆写onActivityResult
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_SELECT_IMAGE && resultCode == Activity.RESULT_OK) { if (data != null) { imageUri = data.getData(); } reloadAndDetectImage(true, false); } else if (resultCode == REQUEST_SELECT_IMAGE && resultCode == Activity.RESULT_CANCELED) { finish(); } }
将Bitmap建立为MLFrame
srcBitmap = BitmapUtils.loadFromPathWithoutZoom(this, imageUri, IMAGE_MAX_SIZE, IMAGE_MAX_SIZE); MLFrame frame = MLFrame.fromBitmap(srcBitmap);
以后调用asyncAnalyseFrame异步处理方法,对所加载的图片进行超分处理
Task<MLImageSuperResolutionResult> task = analyzer.asyncAnalyseFrame(frame); task.addOnSuccessListener(new OnSuccessListener<MLImageSuperResolutionResult>() { public void onSuccess(MLImageSuperResolutionResult result) { // Recognition success. desBitmap = result.getBitmap(); setImage(desImageView, desBitmap); setImageSizeInfo(desBitmap.getWidth(), desBitmap.getHeight()); } }).addOnFailureListener(new OnFailureListener() { public void onFailure(Exception e) { // Recognition failure. Log.e(TAG, "Failed." + e.getMessage()); Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); } });
识别完成后,中止分析器
if (analyzer != null) { analyzer.stop(); }
同时覆写Activity的onDestroy方法对Bitmap资源进行释放
@Override protected void onDestroy() { super.onDestroy(); if (srcBitmap != null) { srcBitmap.recycle(); } if (desBitmap != null) { desBitmap.recycle(); } if (analyzer != null) { analyzer.stop(); } }
源码
Demo已在相关社区进行开源,欢迎开发者关注、下载并提供宝贵意见:
>>访问华为机器学习服务官网,了解更多相关内容
>>获取华为机器学习服务开发指导文档
>>华为机器学习服务开源仓库地址:GitHub、Gitee
点击右上角头像右方的关注,第一时间了解华为移动服务最新技术~