国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于Android 的易拍畫軟件設(shè)計與實現(xiàn)

2020-10-12 09:20:16胡奇超王贈凱易文亮盧奇
現(xiàn)代計算機 2020年24期
關(guān)鍵詞:簡筆畫輪廓梯度

胡奇超,王贈凱,易文亮,盧奇

(嘉興學(xué)院數(shù)理與信息工程學(xué)院,嘉興 314001)

0 引言

調(diào)查研究發(fā)現(xiàn),年齡在4-7 歲的兒童富于想象力和創(chuàng)造力,特別喜歡隨時隨地勾畫周邊的感興趣物體。這個階段的孩子大部分并不掌握基本的繪畫技巧,實際表現(xiàn)就是在紙上或墻上隨意涂畫。而很多家長并不能在繪畫方面給予孩子很好的指導(dǎo),他們不擅長將身邊看到的任何意思的物體通過寥寥幾筆勾勒出來。雖然網(wǎng)絡(luò)上有一些特定物體的簡筆畫圖案供家長和孩子學(xué)習(xí)參考,但卻無法滿足家長和孩子在任意時間對任意場景中任意物體的簡筆畫圖案的需求。作為計算機應(yīng)用領(lǐng)域中的一個重要技術(shù),圖像處理技術(shù)能夠?qū)?shù)字圖像進行分析、處理和變換,從中抽取出用戶感興趣的東西。基于此,本文試圖利用圖像處理技術(shù)實現(xiàn)一個能夠自動生成感興趣物體簡筆畫圖案的移動端軟件,最大程度地滿足家長和孩子對簡筆畫圖案的需求。

所謂簡筆畫,就是用簡單的線條來勾勒出物體的基本特征,簡筆畫繪制已成為非真實感繪制研究領(lǐng)域的一個重要組成部分[1]。目前最常見的生成簡筆畫的做法是將源圖像轉(zhuǎn)化成灰度圖像,再對灰度圖像進行平滑、銳化圖像增強處理,然后在此基礎(chǔ)上對增強后的圖像進行邊緣檢測[2-5]、邊緣細化、輪廓提取[6-8],對得到的輪廓圖進行分層處理,最后利用LIC 算法模擬產(chǎn)生鉛筆紋理,從而完成圖像的簡筆畫風格[9]。傳統(tǒng)的做法中,使用Canny 邊緣檢測[4]具有定位準、精度高的優(yōu)點;使用圖層的劃分技術(shù)和LIC 算法,能夠較為真實的達到簡筆畫繪制的效果。但也存在一定的缺點,例如傳統(tǒng)的Canny 邊緣檢測算法忽略了圖像的色彩信息、人為設(shè)定上下閾值等,這些缺陷導(dǎo)致檢測結(jié)果中包含了假邊緣或是丟失了某些真實邊緣[10-11],以及LIC 算法需要對各個像素進行卷積,計算量相對較大,比較費時。

本文就如何利用計算機圖像處理技術(shù)開發(fā)基于Android 的“易拍畫”軟件進行論述?!耙着漠嫛避浖ㄟ^對手機拍攝對照片或網(wǎng)上下載的圖片,實現(xiàn)對彩色圖像進行簡筆畫風格轉(zhuǎn)換,得到只具有原圖像輪廓的簡筆畫。這種簡筆畫正適合兒童模仿創(chuàng)造,解決了家長在對兒童進行繪畫指導(dǎo)中可能會碰到的問題。

1 輪廓檢測算法

圖片簡筆畫方案的生成可以利用計算機圖像處理中的輪廓檢測技術(shù)進行自動檢測,其步驟如圖1 所示。

圖1 輪廓檢測步驟

首先獲取源圖像,對源圖像進行灰度處理,對得到的灰度圖像進行邊緣檢測,其中邊緣檢測步驟包括圖像平滑處理、計算梯度值與方向、非極大值抑制、雙閾值檢測連接;最后是輪廓提取,得到輪廓輸出圖像。

1.1 灰度化處理

灰度化處理是將彩色數(shù)字圖像轉(zhuǎn)化為灰度圖像的過程。彩色數(shù)字圖像的每一個像素點都是由紅、藍、綠三個通道組成,分別對這三個通道每個分量分配不同的比重就可以產(chǎn)生世界上所有的顏色。在圖像的RGB模型中,當R=G=B 時,表示為一種灰度顏色,其中R=G=B 的值叫做圖像的灰度值,將圖像進行灰度化處理本質(zhì)上就是使彩色圖像的R,G,B 分量值相等的過程?;叶然幚矸椒╗12]有平均值法,最大值法和加權(quán)平均值法。本文使用基于OpenCV 的圖像灰度化處理,其函數(shù)原型是 CV_EXPORTS_W void cvtColor(InputArray src, OutputArray dst, int code, int dstCn = 0),參數(shù)含義如表1 所示。

表1 cvtColor 函數(shù)參數(shù)說明

1.2 邊緣檢測

邊緣檢測是圖像處理的重要操作,是對圖像進行分割和對象特征提取的關(guān)鍵步驟。當一個像素點的四周像素灰度發(fā)生階躍性變化時,則把這種像素點的集合叫做邊緣。邊緣檢測的算法眾多,而Canny 算子由于其在抑制噪聲和檢測邊緣之間能夠取得較好的平衡,因而被廣泛應(yīng)用。用Canny 算子得到邊緣點的具體算法步驟如下所示:

(1)平滑處理

噪聲對邊緣檢測的算法效果影響很大,需要使用濾波器對圖像進行降噪處理。常用的濾波器有均值濾波器、中值濾波器和高斯濾波器。由于高斯濾波器對去除服從正態(tài)分布的噪聲十分有效,對于去除高斯噪聲也有很好的效果。本文采用高斯濾波器對圖像進行平滑處理,具體使用OpenCV 的GaussianBlur 函數(shù)進行濾波,函數(shù)原型是void GaussianBlur(Mat src, Mat dst,Size ksize, double sigmaX, double sigmaY, int border-Type),參數(shù)說明如表 2。

表2 GaussianBlur 函數(shù)參數(shù)說明

(2)計算梯度幅值與方向

平滑后的圖像使用3×3 的一階有限差分進行圖像的梯度幅值與方向計算。圖像的邊緣有不同方向的指向,Canny 算子用了四個梯度算子分別計算水平、垂直和對角線方向的梯度。要計算水平和垂直方向的差分Gx和Gy,可以使用邊緣差分算子進行計算,計算梯度模和方向的公式如下,Gx,Gy分別代表x,y方向的梯度,θ代表梯度角度:

梯度角度θ的范圍為-π到π,把它近似到四個方向,分別代表水平,垂直和兩個對角線方向(0°,45°,90°,135°)。以 ±iπ/8(i=1,3,5,7)分割,給每個區(qū)域中下降的梯度角一個特定值,以表示四個方向之一。

(3)非極大值抑制

Canny 算子針對梯度幅值進行非極大值抑制。通過檢測同一梯度方向上每個像素點的梯度幅值,判斷其是否為局部最大值。如果該點的梯度幅值不是最大值,則對應(yīng)的灰度值將被設(shè)置為0,如此大多數(shù)非邊緣點就可以被移除。如果該點的梯度幅值是最大值,它將被保留為邊緣點。

(4)滯后閾值處理

要確定圖像的哪些邊界才是真正的邊界。如圖2所示,需要設(shè)置兩個閾值:minVal 和maxVal,當圖像的灰度梯度高于maxVal 時被認為是真的邊界,而低與minVal 的則被拋棄。如果介于兩者之間的話,則判斷這個點是否與某個被確定為真正邊界的點相連,如果是就認為這個點是邊界點,如果不是就拋棄。

圖2 滯后閾值示意圖

A 高于閾值maxVal 所以是真正的邊界點,C 介于maxVal 與minVal 之間并與A 相連,所以也被認為是真正的邊界點。而B 就會被拋棄,其低于maxVal 且不與真正的邊界點相連。所以選擇合適的maxVal 和min-Val 對于能否取得好的邊緣十分重要。

1.3 輪廓提取

輪廓簡單來說就是一系列邊緣的集合,通過對一系列的邊緣進行組合就可以得到一個完整的輪廓。用Canny 邊緣檢測算子對二值化后的圖像進行處理后,得到只含邊緣的二值圖像。通過基于OpenCV 的find-Contours 函數(shù)對得到的只含邊緣的二值化圖像進行輪廓提取,再通過drawContours 函數(shù)就可將輪廓繪制出來得到了輪廓圖。findContours 函數(shù)原型是void find-Contours(InputOutputArray image, OutputArrayOfArrays contours,OutputArray hierarchy, int mode,int method,Point offset=Point()),參數(shù)說明如表3。

drawContours 函數(shù)原型 void drawContours( Input-OutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color,int thickness = 1, int line-Type = LINE_8, InputArray hierarchy = noArray(),int maxLevel=INT_MAX,Point offset=Point())是,參數(shù)說明如表4。

表3 findContours 函數(shù)參數(shù)說明

表4 drawContours 函數(shù)參數(shù)說明

2 “易拍畫”軟件設(shè)計

本文在基于傳統(tǒng)做法基礎(chǔ)上做出了一定的改進。在傳統(tǒng)的Canny 邊緣檢測算法的基礎(chǔ)上,進行了對梯度幅值進行非極大值抑制;用雙閾值算法檢測和連接邊緣等操作提升了效果。具體使用的圖像處理操作基于 OpenCV 開源庫[13-14]。

2.1 總體架構(gòu)

本文實現(xiàn)一個基于Android 移動端的“易拍畫”軟件,主要功能為將彩色圖像轉(zhuǎn)簡筆畫風格圖像[15-16]。將通過拍照或下載得到的源圖像進行灰度化處理,將得到的灰度圖像通過Canny 邊緣檢測算法對其進行模糊、去噪得到邊緣圖像,在得到的邊緣圖像的基礎(chǔ)上提取其輪廓,然后對圖像進行分層處理,提出了適用于圖層的白噪聲生成方法,最后采用快速積分卷積(FLIC)替代傳統(tǒng)線積分卷積)LIC)進行模擬紋理[17],并將各層結(jié)果以及圖像輪廓進行疊加生成簡筆畫[18-20]。軟件的功能架構(gòu)如圖3 所示。

圖3“易拍畫“軟件的功能架構(gòu)

“易拍畫”軟件包括4 個主要功能。本地相冊選圖:用戶通過選擇本地相冊的圖片,裁剪后作為簡筆畫的原圖像。拍照取圖:用戶啟動手機的相機拍照,拍完照片后裁剪,作為簡筆畫的原圖像。簡筆畫生成:基于OpenCV 開源庫對用戶選擇的圖像進行處理后得到簡筆畫。保存簡筆畫:將生成的鉛筆畫保存到系統(tǒng)目錄下。

2.2 本地相冊

功能描述:此功能按鈕通過用戶直接選擇相冊中的圖片以便進行之后的裁剪并簡筆畫操作。

實現(xiàn)方法:checkReadPermission()是處理執(zhí)行時的權(quán)限的邏輯的函數(shù),判斷是否被授權(quán),授權(quán)時直接進行操作,未授權(quán)時根據(jù)請求結(jié)果進行處理。請求處理結(jié)果在onRequestPermissonsResult()函數(shù)中。這里,執(zhí)行權(quán)限申請按組處理,即屬于同一組的權(quán)限要求相同,如果用戶授權(quán)一個權(quán)限,同一組的權(quán)限也同時授權(quán)。SD 卡的讀寫都屬于STORAGE 組,所以在申請SD 卡的讀寫權(quán)限的時候申請讀寫權(quán)限或者寫權(quán)限就可以了。之后調(diào)用choseHeadImageFromGallery()函數(shù)處理Intent 的 Activity,請求碼是 CODE_GALLERY_REQUEST。

2.3 拍照選圖

功能描述:此功能按鈕通過用戶拍照并顯示圖片以便進行之后的裁剪并簡筆畫操作。

實現(xiàn)方法:checkStoragePermission()函數(shù)同樣用于處理運行時權(quán)限的邏輯,需要Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STOR -AGE 這兩個權(quán)限,判斷是否被授權(quán),授權(quán)時直接進行操作,未授權(quán)時根據(jù)請求結(jié)果進行處理。之后調(diào)用choseHeadImageFromCameraCapture()函數(shù)。addflags的作用是標記Intent,允許Intent 啟動的Activity 使用FileProvider 封裝的Uri。接著啟動Activity,請求代碼為CODE_CAMERA_REQUEST。由此,完成拍攝請求,轉(zhuǎn)移到系統(tǒng)的拍攝接口,接著處理拍攝的照片。

從Android 7.0(SDK>=24)開始,直接使用本地真實的URI 被認為是不安全的,會拋出一個FileUriExposedException 異常,需要使用 FileProvider 上封裝的URI。FileProvider 的使用:新建 provider_paths.xml,paths指定要使用的目錄,external-path 為SD 卡根目錄,接下來,在AndroidManifest.xml 中注冊provider。grantU-riPermissions 設(shè)為true,以允許系統(tǒng)相機臨時使用此provider。authorities 與此前使用FileProvider 時一樣,exported 必須為false,否則將返回錯誤。

2.4 照片裁剪

功能描述:此功能用于將本地相冊選的圖片或拍照選的圖片進行裁剪以達到用戶所期望的圖片。

實現(xiàn)方法:cropRawPhoto(Uri uri)函數(shù)參數(shù)為拍照或本地圖片得到的圖片的Uri,創(chuàng)建com.android.camera.action.CROP 的 Intent,通過 intent.putExtra 方法設(shè)置裁剪的大小比例,然后將裁剪好的圖輸出到所建文件中,圖片裁剪完成后回調(diào)的是case CODE_RESULT_REQUEST 下 的 setImageToHeadView(Intent a,Bitmap b)方法提取保存裁剪之后的圖片數(shù)據(jù),并設(shè)置圖像部分的View。

intent.putExtra("return-data", false)函數(shù)參數(shù) return-data 應(yīng)設(shè)置為false,如果設(shè)置為true,那么裁剪后的圖像直接以Bitmap 形式緩存到內(nèi)存中,但Bitmap 相當大,如果手機內(nèi)存不足或分配給手機的內(nèi)存不足,就會因OOM 問題而閃退。

2.5 簡筆畫保存

功能描述:此功能用于將生成的簡筆畫保存到手機本地相冊。

實現(xiàn)方法:設(shè)置點擊監(jiān)聽器setOnClickListener,用戶點擊后調(diào)用saveImage()方法,首先獲取ImageView,開啟 DrawingCache,通過 getDrawingCache 方法獲取ImageView 的Bitmap 格式的圖像并調(diào)用saveBitmap-File()方法保存獲取的圖像,關(guān)閉DrawingCache,顯示Toast“已保存”。saveBitmapFile()方法中獲取系統(tǒng)時間并賦給圖像名ImgName,new File("/sdcard/1StickFigure/")創(chuàng)建文件夾,new File("/sdcard/1StickFigure/"+ImgName+".jpg")將要保存圖片的路徑和圖片名稱,new FileOutputStream(file)保存到系統(tǒng)本地相冊。

3 效果與評價

3.1 軟件的實現(xiàn)

“易拍畫”軟件的開發(fā)環(huán)境為Android Studio 3.5.2,開發(fā)語言是Java 語言,利用JDK1.8 和開源圖像處理工具OpenCV 3.4.3。由于Android 6.0 引入了運行時權(quán)限,用戶不必在安裝時授予所有權(quán)限,可以在使用到相關(guān)功能時再授權(quán)。

圖4 展示了“易拍畫”軟件界面,界面中間是用來顯示圖像的ImageView 控件,點擊本地相冊和拍照選圖按鈕,分別是拍照和相冊選擇圖片功能,其中都實現(xiàn)了照片的自動裁剪。裁剪后的圖片通過ImageView 控件顯示。如圖4 所示,可見在背景較為簡單的情況下,彩色圖像的輪廓能很好地繪制出來,生成的輪廓完整清晰,無假邊緣,并且實際生成時間在1 秒之內(nèi),一定程度上滿足了用戶對簡筆畫效果和等待時間的需求。

圖4 易拍畫軟件實現(xiàn)效果圖

3.2 輪廓檢測效果測試

我們分別用不同類型的圖片對本文輪廓檢測算法進行來測試,其中部分實驗效果如圖5 所示??梢钥吹讲煌瑘鼍跋?,輪廓效果都較為完整。但在背景較復(fù)雜、物體細節(jié)特征較多的情況下,輪廓的丟失以及細節(jié)處理方面都還需要進一步改進。

3.3 用戶評價

依據(jù)軟件的實際使用人群分別對四個年齡段的人群進行調(diào)研打分,每組15 人分別打分,從邊緣檢測效果圖的邊緣完整性、邊緣準確性、實際觀看效果三個方面對效果圖進行了綜合評價,表5 給出了評分依據(jù)。評分結(jié)果如表6 所示。

圖5 輪廓檢測示例

第一行是源圖像,第二行是檢測結(jié)果

表5 評分依據(jù)

另外,選取10 組親子家庭實際使用“易拍畫”軟件,在他們使用了一段時間后,分別從軟件的易用性、界面設(shè)計、性能上進行評判,評判結(jié)果如表7 所示。

表6 評分結(jié)果表

表7 評分結(jié)果表

4 結(jié)語

本文提出了利用圖像處理技術(shù)進行簡筆畫圖像生成的方法,并利用OpenCV 開源庫實現(xiàn)了基于Android平臺“易拍畫”軟件。經(jīng)測試表明,所提出的方法可行,“易拍畫”軟件的實現(xiàn)效果能夠滿足用戶的基本需求,但仍然存在進一步改進的空間。可以通過使用不同場景下多樣的濾波來代替單一高斯濾波,來改進Canny算子的邊緣檢測效果;在輪廓提取上可以使用輪廓近似來使輪廓更加完整。由于Android 手機的限制,簡筆畫圖像生成速度也需進一步改善;在具有復(fù)雜背景的輸入圖片情況下,簡筆畫效果圖需要在輪廓精確性和簡化輪廓層次兩個方面進一步平衡和提升。

猜你喜歡
簡筆畫輪廓梯度
一個改進的WYL型三項共軛梯度法
OPENCV輪廓識別研究與實踐
萌寵簡筆畫
神形兼?zhèn)涞暮喒P畫
一種自適應(yīng)Dai-Liao共軛梯度法
基于實時輪廓誤差估算的數(shù)控系統(tǒng)輪廓控制
一類扭積形式的梯度近Ricci孤立子
超贊的簡筆畫
在線學(xué)習(xí)機制下的Snake輪廓跟蹤
計算機工程(2015年4期)2015-07-05 08:27:39
地溫梯度判定地熱異常的探討
河南科技(2014年3期)2014-02-27 14:05:45
句容市| 苍南县| 龙山县| 自治县| 桓台县| 饶阳县| 开平市| 甘孜| 海阳市| 阿鲁科尔沁旗| 乌兰察布市| 金塔县| 古田县| 勐海县| 英吉沙县| 洪泽县| 时尚| 天台县| 古田县| 新蔡县| 峨眉山市| 天峨县| 安宁市| 保山市| 东兴市| 永修县| 丰原市| 嘉鱼县| 婺源县| 大化| 宝丰县| 张北县| 会同县| 山东| 瑞昌市| 蒲江县| 延吉市| 淅川县| 沙洋县| 平江县| 邵阳市|