当前位置: 首页 > 编程语言 > C#

确定图像倾斜的有效方法分享

时间:2023-04-11 02:50:59 C#

C#学习教程:确定图像倾斜的有效方法该图像具有以下属性:到目前为止,我已经想出了这个策略:从左到右绘制一条路线,始终选择最近的白色像素。据推测,从左到右的路线更愿意遵循图像倾斜的文本行之间的路径。这是我的代码:privateboolIsWhite(Colorc){returnc.GetBrightness()>=0.5||c==Color.Transparent;}privateboolIsBlack(Colorc){return!IsWhite(c);}privatedoubleToDegrees(decimalslope){return(180.0/Math.PI)*Math.Atan(Convert.ToDouble(slope));}privatevoidGetSkew(Bitmapimage,outdoubleminSkew,outdoublemaxSkew){decimalminSlope=0.0M;十进制最大斜率=0.0M;对于(intstart_y=0;start_y=above&¢er>=below){/*endY不变*/}elseif(above>=center&&above>=below){endY=aboveY;}elseif(below>=center&&below>=above){endY=belowY;}itemsInSet++;sumOfX+=x;sumOfY+=endY;sumOfXX+=(x*x);sumOfXY+=(x*endY);}//最小二乘斜率=(NΣ(XY)-(ΣX)(ΣY))/(NΣ(X^2)-(ΣX)^2),其中N=集合中的元素if(itemsInSet>image.Width/2)//路径至少覆盖图像的一半{decimalsumOfX_d=Convert.ToDecimal(sumOfX);十进制sumOfY_d=Convert.ToDecimal(sumOfY);十进制sumOfXY_d=Convert.ToDecimal(sumOfXY);十进制sumOfXX_d=Convert.ToDecimal(sumOfXX);十进制itemsInSet_d=Convert.ToDecimal(itemsInSet);小数斜率=((itemsInSet_d*sumsOfXOfX)-(sumOfY_d))/((itemsInSet_d*sumOfXX_d)-(sumOfX_d*sumOfX_d));slopes.AddLast(Convert.ToDouble(slope));}}双均值=slopes.Average();双sumOfSquares=slopes.Sum(d=>Math.Pow(d-mean,2));双stddev=Math.Sqrt(sumOfSquares/(slopes.Count-1));//选择平均值在1个标准偏差范围内的项目vartestSample=slopes.Where(x=>Math.Abs??(x-mean),导致斜率接近于0,导致代码低估了图像的实际斜率。通过选择随机样本点和对所有点进行采样,倾斜精度没有明显差异,因为选择的“平坦”路径的比例随机采样与整个图像中“平坦”路径的比例相同。GetPixel很慢。您可以使用此处列出的方法更好地获得一个数量级。如果文本是左(右)对齐,则可以确定斜率通过测量图像的左(右)边缘和两个随机位置的第一个暗像素之间的距离,并从中计算斜率。额外的测量可以减少错误,同时花费额外的时间。首先,我必须说我喜欢这个想法.但我以前从未这样做过,而且我不确定要提出什么建议来提高可靠性。我最先能想到的就是抛出统计异常的想法。如果斜率突然急剧变化,那么您就知道您发现图像的白色部分向边缘倾斜(没有双关语意)您的结果。所以你想以某种方式把那些东西扔掉。但是从性能的角度来看,您可以进行一些可能会增加的优化。也就是说,我将从内部循环更改此代码段:Colorcenter=image.GetPixel(x,end_y);上面的颜色=image.GetPixel(x,above_y);下面的颜色=image.GetPixel(x,below_y);if(IsWhite(center)){/*end_y没有变化*/}elseif(IsWhite(above)&&IsBlack(below)){end_y=above_y;}elseif(IsBlack(above)&&IsWhite(below)){end_y=below_y;为此:Colorcenter=image.GetPixel(x,end_y);if(IsWhite(center)){/*end_y不变*/}else{Colorabove=image.GetPixel(x,above_y);下面的颜色=image.GetPixel(x,below_y);if(IsWhite(above)&&IsBlack(below)){end_y=above_y;}elseif(IsBlack(above)&&IsWhite(below)){end_y=below_y;}}这是相同的效果,但应该大大减少对GetPixel的调用次数。还可以考虑在疯狂开始之前将不可变值放入变量中。像image.Height和image.Width这样的东西每次被调用时都会有轻微的开销。所以在循环开始前把那些值存入你自己的变量中。在处理嵌套循环时,我总是告诉自己的事情是优化内部循环中的所有内容,而牺牲其他所有内容。另外...正如VinkoVrsalovic所建议的那样,您可以查看他的GetPixel替代方案以获得额外的速度。乍一看,您的代码看起来过于幼稚。这解释了为什么它并不总是有效。我喜欢SteveWortham建议的方法,但如果您有背景图片,它可能会遇到问题。另一种通常有助于图像的方法是先模糊它们。如果你足够模糊示例图像,每一行文本最终都会变成模糊的平滑线。然后你应用某种算法基本上做回归分析。有很多方法可以做到这一点,网上也有很多例子。边缘检测可能有用,也可能会导致更有价值的问题。顺便说一句,如果你足够搜索代码,高斯模糊可以非常有效地实现。否则,我相信有很多可用的库。最近没有做太多事情,所以手头没有任何链接。但是搜索图像处理库可以得到很好的结果。我假设您在解决这个问题时很开心,所以这里没有太多实际的实现。测量每条线的角度似乎有点矫枉过正,尤其是考虑到GetPixel的性能。我想知道通过在左上角或右上角(取决于倾斜方向)寻找白色三角形并测量斜边的角度是否会获得更好的性能。页面上的所有文本都应遵循相同的角度,并且页面的左上角不应被上面内容的掉落或空格所欺骗。另一个需要考虑的技巧:不要模糊,而是在大大降低的分辨率下工作。这将为您提供更流畅的数据和更少的GetPixel调用。例如,我在.NET中为传真的TIFF文件执行了一个空白页检测例程,该例程只是将整个页面重新采样为单个像素并测试该值的白色阈值。你的时间限制是什么?霍夫变换是一种非常有效的确定图像倾斜角度的机制。这可能会花费很多时间,但如果您要使用高斯模糊,就会消耗大量CPU时间。还有其他方法可以加快涉及创意图像采样的霍夫变换。你最新的输出让我很困惑。当您将蓝线叠加到源图像上时,您是否稍微偏移了它?看起来蓝线比文本中心高约5个像素。不确定那个偏移量,但你肯定有派生线以错误的角度“漂移”的问题。它似乎过于偏向于生成水平线。我想知道将遮罩窗口从3个像素(中心,一个在上面,一个在下面)增加到5个像素是否可以改善这一点(两个在上面,两个在下面)。如果您按照richardtallent的建议对较小的图像重新取样,您也会得到这种效果。很酷的寻路应用程序。我想知道这种其他方法是否会帮助或影响您的特定数据集。假设黑白图像:我想如果事实上你必须考虑真正的-45->+45度倾斜,这将不会很好地工作。如果实际数字较小(?+/-10度),这可能是一个非常好的策略。获得初始结果后,您可以考虑以较小的阶数增量重新运行以微调答案。所以我可能会尝试使用一个函数来编写它,该函数将float_tick作为参数,这样我就可以使用相同的代码同时运行粗略和精细(或粗略或精细频谱)。这在计算上可能很昂贵。要优化,您可以考虑只选择图像的一部分进行项目测试旋转重复。以上就是C#学习教程的全部内容:判断图像倾斜度的有效方法。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处: