非真实渲染

非真实感渲染(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实现非真实渲染的资料请关注Devmax其它相关文章!

Android基于OpenCV实现非真实渲染的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. iOS使用openCV检测来自摄像头的矩形

    如果我在处理它之前克隆matimage,通过记录它,它似乎处理图像甚至找到矩形,但矩形不会被绘制到图像输出到imageView.我很确定我错过了一些东西,可能是因为我没有正确传递某个对象,指向对象的指针等等,而我需要修改的对象则没有.无论如何,如果这不是正确的方法,我真的很感谢他们做这样的事情的教程或例子,使用openCV或GPUImage…它不需要尝试使用matimage来设置imageView.image,而只需要将matimage转换为在imageView中实际修改,因为CvVideoCamera已

  8. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  9. 使用Xcode为OS X Lion / Mountain Lion编译OpenCV(2.3.1)

    任何人都可以为我提供一些如何使用Xcode在OSXLion上编译OpenCV2.3.1的详细指南吗?我对此感到生气…我得到了源码,使用cmake创建Xcode模板并尝试构建它,但它失败了大约200个错误.提前致谢,大教堂解答我的回答帖子.解决方法详细指南如何使用MacPorts在Xcode4.2.1的OSXLion下启动和运行OpenCV2.3.1编辑08/06/2012:这也适用于OpenCV2.4.1.只需确保您获得最新版本的Xcode并安装“命令行工具”.编辑15/08/2012:使用Mountai

  10. ios – OpenCV构建问题,找不到ext/atomicity.h

    我得到编译器错误抱怨在构建包含OpenCV的项目时.环境是针对iOS的Xcode4.5.它为模拟器编译良好,但在为设备构建时失败.这是错误文本:我正在使用opencv2.framework,使用指令here构建cmake.解决方法默认情况下,XCode4.5使用libc(支持C11的LLVMC标准库)生成要构建的新项目.但OpenCV期望针对GNUlibstd

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部