誰家沒幾張有魔力的老照片,雖然背景簡單、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
點擊右上角頭像右方的關注,第一時間瞭解華爲移動服務最新技術~