Android基于OpenCV实现非真实渲染
非真实渲染
非真实感渲染(Non Photorealistic Rendering,简称NPR),是指利用计算机模拟各种视觉艺术的绘制风格,也用于发展新的绘制风格。比如模拟中国画、水彩、素描、油画、版画等艺术风格。NPR也可以把三维场景渲染出丰富的、特别的新视觉效果,使它具备创新的功能。NPR渲染以强烈的艺术形式应用在动画、游戏等娱乐领域中,也出现在工程、工业设计图纸中。广阔的应用领域,不仅是由于它的艺术表现形式丰富多样,还在于计算机能够辅助完成原本工作量大、难度高的创作工作。 目前,基于三维软件的NPR渲染器相当多,如FinalToon, Il-lustrator, Pencil等,同时还可以借用程序贴图来创建NPR的材质,协助生成手绘风格的图像效果;另外,像Mental Ray,Reyes,Brazil等外挂渲染器都是NPR渲染的解决方案
引用自【百度百科】
API
OpenCV给我们提供了四种非真实渲染的使用场景:边缘保留滤波、细节增强、素描铅笔画、风格化。
边缘保留滤波
public static void edgePreservingFilter(Mat src, Mat dst, int flags, float sigma_s, float sigma_r)
- 参数一:src,输入图像,8位三通道。
- 参数二:dst,输出图像,8位三通道。
- 参数三:flags,边缘保留标志位。
public static final int RECURS_FILTER = 1, NORMCONV_FILTER = 2;
- 参数四:sigma_s,邻域大小。取值0~200。
- 参数五:sigma_r,邻域内被平均的颜色的不相近程度。取值0~1。
细节增强
public static void detailEnhance(Mat src, Mat dst, float sigma_s, float sigma_r)
- 参数一:src,输入图像,8位三通道。
- 参数二:dst,输出图像,8位三通道。
- 参数三:sigma_s,邻域大小。取值0~200。
- 参数四:sigma_r,邻域内被平均的颜色的不相近程度。取值0~1。
素描铅笔画
public static void pencilSketch(Mat src, Mat dst1, Mat dst2, float sigma_s, float sigma_r, float shade_factor)
- 参数一:src,输入图像,8位三通道。
- 参数二:dst1,输出图像,8位单通道,即黑白素描。
- 参数三:dst2,输出图像,大小类型与输入图像相同,即彩色素描。
- 参数四:sigma_s,邻域大小。取值0~200。
- 参数五:sigma_r,邻域内被平均的颜色的不相近程度。取值0~1。
- 参数六:shade_factor,强度缩放值。取值0~0.1
风格化
public static void stylization(Mat src, Mat dst, float sigma_s, float sigma_r)
- 参数一:src,输入图像,8位三通道。
- 参数二:dst,输出图像,8位三通道。
- 参数三:sigma_s,邻域大小。取值0~200。
- 参数四:sigma_r,邻域内被平均的颜色的不相近程度。取值0~1。
关于sigma_s和sigma_r:
sigma_s,即Sigma_Spatial,决定平滑量。sigma_r,即Sigma_Range,决定平均值。
典型的平滑滤波器将像素值替换为其相邻像素的加权和。 邻域越大,过滤后的图像看起来越平滑。 邻域的大小与参数sigma_s成正比。但是在边缘保留滤波器里,有两个关键点:1)平滑图片;2)不平滑边缘/颜色边界。换句话说,我们就无法简单地将像素值替换成邻域像素的加权和。而是在邻域内选取和当前像素值相近的像素然后求取平均值,然后替换当前像素值的方式来避免上述问题。所以就需要两个参数来明确范围和颜色相似程度。
操作
/** * 非真实渲染 * * @author yidong * @date 11/30/20 */ class NonPhotoRealisticRenderingActivity : AppCompatActivity() { private lateinit var mRgb: Mat private val mBinding: ActivityNonPhotorealisticRenderingBinding by lazy { ActivityNonPhotorealisticRenderingBinding.inflate(layoutInflater) } private var sigmaR = 10f set(value) { field = when { value > 200f -> { 200f } value < 0f -> { 200f } else -> { value } } mBinding.tvSigmaR.text = sigmaR.toInt().toString(10) } private var sigmaS = 0.1f set(value) { field = when { value > 1.0f -> { 1.0f } value < 0f -> { 0f } else -> { value } } mBinding.tvSigmaS.text = String.format("%.1f", sigmaS) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(mBinding.root) mRgb = Mat() val bgr = Utils.loadResource(this, R.drawable.cow) Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB) mBinding.ivLena.showMat(mRgb) } private fun doEdgePreservingFilter(flag: Int) { val dst = Mat() mBinding.isLoading = true GlobalScope.launch(Dispatchers.IO) { Photo.edgePreservingFilter(mRgb, dst, flag, sigmaR, sigmaS) launch(Dispatchers.Main) { mBinding.isLoading = false mBinding.ivResult.showMat(dst) } } } private fun doDetailEnhance() { val dst = Mat() mBinding.isLoading = true GlobalScope.launch(Dispatchers.IO) { Photo.detailEnhance(mRgb, dst, sigmaR, sigmaS) launch(Dispatchers.Main) { mBinding.isLoading = false mBinding.ivResult.showMat(dst) } } } private fun doPencilSketch() { val dst1 = Mat() val dst2 = Mat() mBinding.isLoading = true GlobalScope.launch(Dispatchers.IO) { Photo.pencilSketch(mRgb, dst1, dst2, sigmaR, sigmaS, 0.03f) launch(Dispatchers.Main) { mBinding.isLoading = false mBinding.ivResult.showMat(dst2) } } } private fun doStylization() { val dst = Mat() mBinding.isLoading = true GlobalScope.launch(Dispatchers.IO) { Photo.stylization(mRgb, dst, sigmaR, sigmaS) launch(Dispatchers.Main) { mBinding.isLoading = false mBinding.ivResult.showMat(dst) } } } override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.menu_non_photorealistic_rendering, menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { title = item.title when (item.itemId) { R.id.photo_edge_preserving_normconv_filter -> { doEdgePreservingFilter(Photo.NORMCONV_FILTER) } R.id.photo_edge_preserving_recurs_filter -> { doEdgePreservingFilter(Photo.RECURS_FILTER) } R.id.photo_detail_enhance -> { doDetailEnhance() } R.id.photo_pencil_sketch -> { doPencilSketch() } R.id.photo_stylization -> { doStylization() } } return true } fun incSigmaR(view: View) { this.sigmaR = this.sigmaR.plus(1.0f) if (this.sigmaR > 200.0f) { this.sigmaR = 200f } } fun decSigmaR(view: View) { this.sigmaR = this.sigmaR.minus(1.0f) if (this.sigmaR < 0f) { this.sigmaR = 0f } } fun incSigmaS(view: View) { this.sigmaS = this.sigmaS.plus(.1f) if (this.sigmaS > 1.0f) { this.sigmaS = 1f } } fun decSigmaS(view: View) { this.sigmaS = this.sigmaS.minus(.1f) if (this.sigmaS < 0f) { this.sigmaS = 0f } } }
效果
以上就是Android基于OpenCV实现非真实渲染的详细内容,更多关于Android OpenCV实现非真实渲染的资料请关注猪先飞其它相关文章!
相关文章
- 这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 这篇文章主要介绍了vue 获取到数据但却渲染不到页面上的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-19
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- 图片剪裁是常用的方法,那么如何通过4坐标剪裁图片,本文就详细的来介绍一下,感兴趣的小伙伴们可以参考一下...2021-06-04
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了OpenCV如何去除图片中的阴影的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
- 本文主要介绍了mini-vue渲染的简易实现,主要简单来实现一个虚拟dom渲染真实dom,以及更新的方法。具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-08
- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
- 这篇文章主要介绍了python OpenCV的相关资料,帮助大家更好的理解和学习使用python的opencv,感兴趣的朋友可以了解下...2021-03-31
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02