Cocos2dx 如何实现对背景进行模糊处理以达到突出某一个Sprite?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cocos2dx 如何实现对背景进行模糊处理以达到突出某一个Sprite?相关的知识,希望对你有一定的参考价值。

参考技术A 动作(Actions)
move移动:moveto/moveby 从一个位置移动到另外一个位置 从一个位置移动多少数量级
rotate旋转:rotateto/rotateby 从一个角度旋转到另外一个角度 旋转多少个数量级
scale缩放:scaleto/scaleby 放大缩小到什么程度
skew倾斜:skewto/skewby 倾斜到什么程度
rotationalskew旋转着倾斜:rotationalskewto/rotationalskewby 旋转着倾斜
Skew+scale+rotate倾斜+缩放+旋转
jump跳跃:jumpto/jumpby 跳跃到某个位置,或者以某个数量接跳跃
cardinalspline,catmullrom沿着某个路径移动:沿着某个图形移动,可以是规则的图形也可以是不规则图形
bezier两个精灵重叠在一起一个在前面,一个在后面:bezierto/bezierby
blink一闪一闪的效果
fadein/fadeout淡入淡出效果
tint色彩:tintto/tintby 改变小精灵的色彩
animation动画:让小精灵呈现动态效果
sequence:move+rotate:移动加旋转序列
sequence:move+rotate+scale+removeself:移动,旋转,缩放,让自己消失
spawn:jump+rotate:一边跳一边旋转,向翻跟斗一样
reverse an action:执行一个动作相反的动作
delaytime延迟时间:move+delay+move移动+延迟一段时间+移动
repeat/repeatforever:重复执行或者永久重复执行动作
reverse a sequence:反向执行一个序列
orbit camera:轨道摄像机
pauseresumeactions:暂定和继续actions

过渡(transitions)
所谓过渡也就是第一个场景如何过渡到第二个场景,可以添加很多效果。
CCTransitionProgressInOut:一个场景以一个长方形的形式逐渐变大,然后显示另外一个场景。
CCTransitionProgressOutIn:一个场景逐渐变小,直到消失,是通过一个大长方形到一个小长方形消失的,然后组件显示第二个场景,先显示的是第二个场景外围的区域,然后再显示第二个场景里面区域。
CCTrasitionCrossFade:一个场景渐出,一个场景渐入
TransitionPageForward:向前翻页效果
TransitionPageBackward:向后翻页效果
CCTransitionFadeTR:第一个场景从左下角开始淡出一直到右上角,第二个场景从左下角开始淡入一直到右上角
CCTransitionFadeBL:第一个场景从右上角开始淡出一直到左下角,第二个场景从右上角开始淡入一直到左下角
CCTransitionFaceUp:第一个场景从底部开始淡出一直到顶部,第二个场景从底部开始淡入一直到顶部
CCTransitonFadeDown:第一个场景从顶部开始淡出一直到底部,第二个场景从顶部开始淡入一直到底部
CCTransitionTurnOffTiles:以随机的顺序关闭掉外出的场景的砖瓦
CCTransitionSplitRows:奇数行向左出,偶数行向右出
CCTransitionSplitCols:奇数行向下出,偶数行向上出
CCTransitionFade:出去的场景淡出,屏幕变黑,进来的场淡入
FadeWhileTransition:出去的场景淡出,屏幕变白,进来的场淡入
FlipXLeftOver:沿着X从左翻转
FlipXRightOver:沿着X从右翻转
FlipYUpOver:沿着Y从上,翻转
FlipYDownOver:沿着Y从下翻转
FlipAngularLeftOver:从某个角度在左边翻转场景
FlipAngularRightOver:从某个角度在右边翻转场景
FlipAngularUpOver:从某个角度在上边翻转场景
FlipAngularDownOver:从某个角度在下边翻转场景
ZoomFlipXLeftOver:沿着X从左翻转,而且有放大缩小效果
ZoomFlipXRightOver:沿着X从右翻转,而且有放大缩小效果
ZoomFlipYUpOver:沿着Y从上翻转,而且有放大缩小效果
ZoomFlipYDownOver:沿着Y从下翻转,而且有放大缩小效果
ZoomFlipAngularLeftOver:沿着某个角度从左翻转,而且有放大缩小效果
ZoomFlipAngularRightOver:沿着某个角度从右翻转,而且有放大缩小效果
CCTransitionShrinkGrow:缩小出去的场景,放大进来的场景
CCTransitionRoToRoom:一边旋转一边缩放
CCTransitionMoveInL:从左边进入
CCTransitinMoveInR:从右边进入
CCTransitionMoveInT:从上边进入
CCTransitionMoveInB:从下边进入
CCTransitionSlideInL:从左边滑动着进入,滑动的过程中把第一个场景推出去了
CCTransitionSlideInR:从右边滑动进入
CCTransitionSlideInT:从上边滑动进入
CCTransitionSlideInB:从下边滑动进入
CCTransitionJumpZoom:跳动加缩放

进度动作actionprogress
参考ActionsProgressTest
SpriteProgressToRadial:精灵沿着径向执行进度动画
SpriteProgressToHorizontal:精灵沿着水平方向执行动画
SpriteProgressToVertical:精灵沿着垂直方向执行动画
SpriteProgressToRadialMidpointChanged:精灵沿着中点改变时的那个径向执行进度动画
SpriteProgressBarVarious:精灵执行进度条动画时,精灵所在的那个条不断变化
SpriteProgressBarTintAndFade:精灵执行进度条动画时,颜色变化,并且有淡出效果
SpriteProgressWithSpriteFrame:并不仅仅是精灵执行动画,精灵所在的整个frame执行动画效果,包括精灵所在的那个frame旁边的填充

特效effects
TurnOffTiles: 以随机的顺序关闭tiles
WavesTiles3D:3D效果摇摆tiles
JumpTiles3D:3D效果tiles跳跃起来,这样就能看到每个tile下面的背景了
SplitRows:将整个场景分成若干行,奇数行往左,偶数行往右
SplitCols:将整个场景分成若干列,奇数列往下,偶数列往上
PageTurn3D:3D翻页效果
Shaky3D:整个页面震动效果
Waves3D:整个页面波动效果
FlipX3D:3D水平方向翻转效果
FlipY3D:垂直方向翻转效果
Lens3D:3D棱镜效果
Ripple3D:3D波纹效果
Liquid:液体晃动效果
Waves:波动效果
Twirl:转动效果
ShakyTiles3D:tiles震动3D效果
ShatteredTiles3D:肢离破碎的tiles3D效果
ShuffleTiles:将所有的tiles混乱排列的效果
FadeOutTRTiles:tiles从左下角向右上角淡出
FadeOutBLTiles:tiles从右上角向左下角淡出
FadeOutUpTiles:tiles从下向上淡出
FadeOutDownTiles:tiles从上向下淡出

点击和移动(ClickAndMove)
ClickAndMoveTestScene:每当点击鼠标左键时,小精灵更随着我们的鼠标移动

整个世界都在旋转(RotateWorld)
RotateWorldTest:整个世界都在旋转,包括小精灵,整个页面,页面里分块旋转

粒子运动组成各种效果(Particle)
下雪,下雨,烟花效果灯。

精灵缓入缓出效果(SrpiteEaseInOut)
EaseIn:缓入
EaseOut:缓出

精灵运动轨迹(MotionStreak)
HighQualityMode/FastMode

绘制原始的各种几何形状(DrawPrimitives)
绘制三角形,曲线,多边形等等

节点(Node)
这个到底是什么意思,不太懂

触碰测试(Touches)
每当小精灵触碰到一个东西时,做一些事情

菜单(Menu)
在屏幕上可以显示若干个菜单项,点击之后可以是一个菜单,也可以做一些事情,比如返回到主菜单,退出游戏,进行一些设置

动作管理器(ActionManager)
通过动作管理器对精灵如何执行一些列动作进行管理。
LogicTest:先执行什么动作再执行什么动作的逻辑进行控制
PauseTest:让一个动作暂停
ResumeTest:继续一个动作
RemoveTest:移除一个动作,从而让Grossini不会碰撞墙壁

层(Layer)
LayerRGBA:两个精灵分别在不同的层,改变每个层的RGBA,从而知道他们是不同的层

场景(Scene)
pushScene()/popScene/popSceneToRoot 这些是常用的在不同的Scene之间切换的方法,所有的场景存放在一个栈之中。

Parallax:Parent and 3 childrens
搞不懂的东西

地图(TiledMap)
用地砖堆砌起来的地图相关展示

时间间隔(Interval)
精灵执行动作的时间间隔,比如从一个地方跳跃到另外一个地方的时间间隔如何控制

标签(Label)
如何使用标签展示数据,以及随着时间的推移更新标签的值

文本输入框(TextInput)
不同的文本输入框,有不同的缺省行为
CCTextFiledTTF:缺省行为是每输入一个字符就跳动一下,并且可以限制字符个数
TextFieldTTF:缺省行为什么也没干

精灵(Sprite)
精灵能够执行一些力动作,比如旋转,缩放等等

时间表(Scheduler)
使用Scheduler利用timeScale实现快进和回退功能

渲染纹理(RenderTexture)
搞不懂

2d纹理
搞不懂

物理引擎Chipmunk,Box2D
物理引擎的测试,比如说模拟一个物体在有重力的环境下等情景。

高级的特效EffectsAdvanced

小键盘(Keypad)

后台音乐播放相关(CocosDenshion)
音乐播放,暂停,回放,音量控制等等

性能优化相关(Performance)
精灵个数啥的,node,纹理,particle,触碰等等相关性能如何优化。

扩展(Extensions)
在extensions中提供给我们的在以后版本中可能会添加到标准api中的类,是一些比较高级和容易使用的功能。

字体(fonts)

和本地化相关(current language)
如何获取本地语言

纹理缓存(TextureCach)
纹理缓存不懂

阴影相关(Shade)

多点触摸(MultiTouch)
多点触摸相关类如何使用

剪切(Clipping)
不懂

文件操作(FileUtils)
如何操作文件相关的演示
人体脊椎各个部分如何运动(spine)
精灵的各个关节如何运动,实现动态精灵效果啥的

模糊图像的阈值 - 第 2 部分

【中文标题】模糊图像的阈值 - 第 2 部分【英文标题】:Threshold of blurry image - part 2 【发布时间】:2012-11-18 07:50:21 【问题描述】:

如何对这个模糊的图像进行阈值处理以使数字尽可能清晰?

在a previous post 中,我尝试对模糊图像(左)进行自适应阈值处理,结果导致数字失真和断开连接(右):

从那时起,我尝试使用this post 中描述的形态闭合操作来使图像的亮度均匀:

如果我对这张图片进行自适应阈值处理,我不会得到明显更好的结果。但是,由于亮度大致均匀,我现在可以使用普通阈值:

这比以前好多了,但是我有两个问题:

    我不得不手动选择阈值。虽然关闭操作会产生均匀的亮度,但其他图像的亮度级别可能会有所不同。 图像的不同部分在阈值水平稍有变化时效果会更好。例如,左上角的 9 和 7 出现部分褪色,应该有一个较低的阈值,而一些 6 已经融合成 8,应该有一个更高的阈值。

我认为回到自适应阈值,但使用非常大的块大小(图像的 1/9)可以解决这两个问题。相反,我最终得到了一个奇怪的“光晕效应”,其中图像的中心更亮,但边缘与正常阈值图像大致相同:

编辑:remi suggested 在形态上打开这篇文章右上角的阈值图像。这不太好用。使用椭圆内核,只有 3x3 足够小,可以避免完全消除图像,即使这样,数字也会出现明显的破损:

Edit2: mmgp suggested 使用维纳滤镜去除模糊。我将this code for Wiener filtering in OpenCV 改编为OpenCV4Android,但它使图像更加模糊!这是使用我的代码和 5x5 内核过滤之前(左)和之后的图像:

这是我改编的代码,它就地过滤:

private void wiener(Mat input, int nRows, int nCols)  // I tried nRows=5 and nCols=5

    Mat localMean = new Mat(input.rows(), input.cols(), input.type());
    Mat temp = new Mat(input.rows(), input.cols(), input.type());
    Mat temp2 = new Mat(input.rows(), input.cols(), input.type());

    // Create the kernel for convolution: a constant matrix with nRows rows 
    // and nCols cols, normalized so that the sum of the pixels is 1.
    Mat kernel = new Mat(nRows, nCols, CvType.CV_32F, new Scalar(1.0 / (double) (nRows * nCols)));

    // Get the local mean of the input.  localMean = convolution(input, kernel)
    Imgproc.filter2D(input, localMean, -1, kernel, new Point(nCols/2, nRows/2), 0); 

    // Get the local variance of the input.  localVariance = convolution(input^2, kernel) - localMean^2 
    Core.multiply(input, input, temp);  // temp = input^2
    Imgproc.filter2D(temp, temp, -1, kernel, new Point(nCols/2, nRows/2), 0); // temp = convolution(input^2, kernel)
    Core.multiply(localMean, localMean, temp2); //temp2 = localMean^2
    Core.subtract(temp, temp2, temp); // temp = localVariance = convolution(input^2, kernel) - localMean^2  

    // Estimate the noise as mean(localVariance)
    Scalar noise = Core.mean(temp);

    // Compute the result.  result = localMean + max(0, localVariance - noise) / max(localVariance, noise) * (input - localMean)

    Core.max(temp, noise, temp2); // temp2 = max(localVariance, noise)

    Core.subtract(temp, noise, temp); // temp = localVariance - noise
    Core.max(temp, new Scalar(0), temp); // temp = max(0, localVariance - noise)

    Core.divide(temp, temp2, temp);  // temp = max(0, localVar-noise) / max(localVariance, noise)

    Core.subtract(input, localMean, input);  // input = input - localMean
    Core.multiply(temp, input, input); // input = max(0, localVariance - noise) / max(localVariance, noise) * (input - localMean)
    Core.add(input, localMean, input); // input = localMean + max(0, localVariance - noise) / max(localVariance, noise) * (input - localMean)

【问题讨论】:

对您的问题有不同的看法(如果不是奇怪的话):如果您可以控制使用的字体,请将其更改为更好的字体。 “更好”意味着让 6 或 9 更难变成 8。也许也让它更大胆。我想在某些时候您会尝试识别这些数字,这就是您提出问题的原因。 不幸的是,我将“在野外”从 Android 用户的相机中识别这些图像,因此无法控制字体。尽管否则这将是一个有用的解决方案。 用另一种方式解决问题:你为什么要让数字更清晰?之后是对它们进行 OCR 吗?或许,您可以通过使用这些数字训练 OCR 并使用 OCR 在图像中检测它们来获得相当不错的结果。 如果您对用户要从中拍照的每个可能的数字都有一个很好的样本,那么直接从这些数字训练可能是明智的。我对前一个短语的措辞使情况不太可能如此。也许它可以使用一类分类器来实现,例如一类 SVM,因为您也缺乏对您不希望成为数字的内容的良好表示。现在,如果您没有断数字或错误连接的数字,那么训练分类器会容易得多。细化它们后,任务就容易多了,也更容易给出正确的结果。 检查 niblack 算法。参见例如***.com/questions/9871084/niblack-thresholding 【参考方案1】:

您可能会尝试的一些提示:

在原始阈值图像(第一张图片右侧有噪点的图像)中应用形态开口。您应该消除大部分背景噪音并能够重新连接数字。

对原始图像使用不同的预处理而不是形态闭合,例如中值滤波器(倾向于模糊边缘)或bilateral filtering,这将更好地保留边缘但计算速度较慢。

就阈值而言,您可以使用 cv::threshold 中的 CV_OTSU 标志来确定全局阈值的最佳值。局部阈值处理可能仍然更好,但使用双边或中值滤波器应该会更好

【讨论】:

CV_OTSU 标志的好主意,效果很好!不幸的是,形态开放在我的阈值图像上效果不佳(请参阅我编辑的帖子)。此外,Astor 在阈值之前有tried median/bilateral filters,它的效果不如关闭+正常阈值。 可能先打开然后关闭会改善仅打开的结果。【参考方案2】:

我尝试使用 Otsu 算法(CV_OTSU - 感谢 remi!)分别对每个 3x3 框进行阈值处理,以确定每个框的最佳阈值。这比对整个图像进行阈值处理要好一些,并且可能更健壮一些。

不过,我们欢迎更好的解决方案。

【讨论】:

对此类文档的有效二值化是 Sauvola 技术(google sauvola + 二值化)。在OpenCV中没有实现,但是很容易实现,可以使用积分图compute the mean and standard deviation of image patches extremely fast。 我在您的图像上尝试了 suvola,我设法获得了相当不错的结果,但实际上,正如 mmgp 所说,通过微调参数。并且可能这组参数仅适用于该图像,但不适用于具有不同条件的图像。【参考方案3】:

我的建议假设您可以识别数独单元,我认为这并没有要求太多。在我看来,第一步尝试应用形态运算符(尽管我真的很喜欢它们)和/或二值化方法是错误的方法。无论出于何种原因(原始摄像机角度和/或移动,以及其他原因),您的图像至少部分模糊。所以你需要通过执行反卷积来恢复它。当然要求完美的反卷积是太过分了,但我们可以尝试一些东西。

其中一个“事物”是Wiener filter,例如,在 Matlab 中,该函数被命名为 deconvwnr。我注意到垂直方向上的模糊,所以我们可以使用一定长度的垂直内核(以下示例中为 10)执行反卷积,并假设输入不是无噪声的(假设为 5%)——我我只是想在这里给出一个非常肤浅的看法,放轻松。在 Matlab 中,您的问题至少可以通过以下方式部分解决:

f = imread('some_sudoku_cell.png');
g = deconvwnr(f, fspecial('motion', 10, 90), 0.05));
h = im2bw(g, graythresh(g)); % graythresh is the Otsu method

以下是一些细胞的结果(原始、otsu、区域生长的 otsu、形态增强图像、具有区域生长的形态增强图像的 otsu、反卷积的 otsu):

@ @@ 987654324 987654325 987654326 @@ @@ 搜索@@ 987654330 987654331 987654332 @@ @@ 搜索@@ 987654336 987654337 @结果结果@ 987654352@

增强图像是通过使用半径为 3 的扁平圆盘执行 original + tophat(original) - bottomhat(original) 生成的。我手动选择了用于区域生长的种子点并手动选择了最佳阈值。

对于空单元格,您会得到奇怪的结果(解卷积的原始和大津):

但我认为你不会有麻烦检测单元格是否为空(全局阈值已经解决了它)。

编辑:

添加了我可以通过不同方法获得的最佳结果:区域增长。我还尝试了一些其他方法,但这是第二好的方法。

【讨论】:

这是一个很有前途的建议。顺便说一句,就上下文而言,我正试图让它在带有手机图片的 Android 上运行。这种方法会通过任意方向的模糊来提高图像质量吗?它会改善您可能在手机图片中看到的其他类型的图像缺陷吗? 我将把我的答案限制在模糊部分,因为其他图像缺陷太广泛了。我在这里展示的是一个具有已知点扩散函数 (PSF) 估计值的反卷积,它是一个垂直函数。有一种称为盲反卷积的方法,它会尝试猜测一个合适的 PSF,可能比我猜的要好。如果您对“去模糊”的一般方法感兴趣,则应该研究这些。 我主要是在寻找能够始终如一地提供高质量数字的东西。如果它只是修复模糊,如果我可以使用适当的二值化算法补偿模糊、照明和其他缺陷,这可能不值得实现(OpenCV 没有内置实现)。你怎么看? 我不认为你可以用二值化算法来补偿模糊,这是一种不同形式的问题。如果您已经确定了数独板,我认为这里的照明不是问题。此外,反卷积有很好的机会提供更强的边缘,使得更简单的二值化器更容易。请记住,在图像处理中没有“始终如一地为 X 提供高质量”之类的东西,其中 X 是正在调查的任何问题。 我在 opencv 中搜索了反卷积并找到了一些可能对您有所帮助的内容:github.com/Itseez/opencv/blob/master/samples/python2/… 和 ibm.com/developerworks/mydeveloperworks/blogs/theTechTrek/entry/…(没有阅读它们,但听起来很有帮助)。【参考方案4】:

如果您愿意花一些时间来处理它,可以使用去模糊技术在处理之前对图片进行锐化。 OpenCV 中还没有任何内容,但如果这是一种成败攸关的事情,您可以添加它。

有很多关于这个主题的文献: http://www.cse.cuhk.edu.hk/~leojia/projects/motion_deblurring/index.html http://www.google.com/search?q=motion+deblurring

还有一些关于 OpenCV 邮件列表的讨论: http://tech.groups.yahoo.com/group/OpenCV/message/20938

您看到的奇怪的“光环效应”可能是由于当自适应阈值位于/接近图像边缘并且它使用的窗口“悬在”边缘时,OpenCV 假设颜色为黑色非图像领域。有一些方法可以纠正这个问题,很可能你会制作一个比相机图像高和宽至少两个完整块大小的临时图像。然后将相机图像复制到它的中间。然后将临时图像的周围“空白”部分设置为相机图像的平均颜色。现在,当您执行自适应阈值时,边缘/附近的数据将更接近准确。它不会是完美的,因为它不是真实的图片,但它会产生比 OpenCV 假设的黑色更好的结果。

【讨论】:

以上是关于Cocos2dx 如何实现对背景进行模糊处理以达到突出某一个Sprite?的主要内容,如果未能解决你的问题,请参考以下文章

用matlab 如何将图片模糊处理

在 QML/Qt 中模糊部分背景图像

如何在不使用背景图像的情况下获得背景磨砂玻璃效果

【iOS开发】生成高斯模糊效果背景

如何将照片变宽,两边填充原照片模糊效果,如图?

小车速度模糊控制系统