去噪:用于验证码图片识别的类续(C#代码)

c#视觉应用开发中如何在C#中进行图像干扰? 以上示例展示了如何在C#中使用Emgu CV进行图像干扰。通过高斯滤波和中值滤波两种常见的降方法,可以有效减少图像中的声,提高图像质量。根据具体应用需求,还可以探索其他更复杂的降算法。在前面的示例中,我们介绍了如何使用高斯滤波和中值滤波进行图像干扰。接下来,我们将介绍更多高级的图像干扰技术,如双边滤波和非局部均值滤波。通过以上示例,我们展示了高斯滤波、中值滤波、双边滤波和非局部均值滤波四种常见的图像干扰技术。这些方法各有优缺,可以根据具体的应用场景选择合适的降方法。Emgu CV。 阅读详情
自从发表了 用于验证码图片识别的类(C#代码)后, 不断有网友下载这个类后,问如何用于一些特定的验证码。总结一下网友们的提问,很多都是不会从复杂背景中提到干净的字符图片来,这主要就是一个去噪问题, 即除去图片上的背景、干扰点、干扰线等信息。这当中要用到很多图像学数学算法,首先声明,本人不是学图像学的,以下方法理论说得不对,敬请多批评指正。
    1、如何设前景/背景的分界值
    UnCodebase类中有一个GetPicValidByValue( int dgGrayValue) 函数,可以得到前景的有效区域,常有人问我前景/背景的分界值dgGrayValue是如何确定的(常用的是灰度128)。这个值的获取是有数学算法,叫最大类间方差法,即图像的前后景的平方差为最大时的值就是我们关心的分界值,对付如 这样较复杂的背景非常管用,下面是具体的C#代码。

        /// <summary>
        
/// 得到灰度图像前景背景的临界值 最大类间方差法,yuanbao,2007.08
        
/// </summary>
        
/// <returns>前景背景的临界值</returns>
        public int GetDgGrayValue()
        {
            
int[] pixelNum = new int[256];           //图象直方图,共256个点
            int n, n1, n2;
            
int total;                              //total为总和,累计值
            double m1, m2, sum, csum, fmax, sb;     //sb为类间方差,fmax存储最大方差值
            int k, t, q;
            
int threshValue = 1;                      // 阈值
            int step = 1;
            
//生成直方图
            for (int i =0; i < bmpobj.Width ; i++)
            {
                
for (int j = 0; j < bmpobj.Height; j++)
                {
                    
//返回各个点的颜色,以RGB表示
                    pixelNum[bmpobj.GetPixel(i,j).R]++;            //相应的直方图加1
                }
            }
            
//直方图平滑化
            for (k = 0; k <= 255; k++)
            {
                total 
= 0;
                
for (t = -2; t <= 2; t++)              //与附近2个灰度做平滑化,t值应取较小的值
                {
                    q 
= k + t;
                    
if (q < 0)                     //越界处理
                        q = 0;
                    
if (q > 255)
                        q 
= 255;
                    total 
= total + pixelNum[q];    //total为总和,累计值
                }
                pixelNum[k] 
= (int)((float)total / 5.0 + 0.5);    //平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值
            }
            
//求阈值
            sum = csum = 0.0;
            n 
= 0;
            
//计算总的图象的点数和质量矩,为后面的计算做准备
            for (k = 0; k <= 255; k++)
            {
                sum 
+= (double)k * (double)pixelNum[k];     //x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和
                n += pixelNum[k];                       //n为图象总的点数,归一化后就是累积概率
            }

            fmax 
= -1.0;                          //类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行
            n1 = 0;
            
for (k = 0; k < 256; k++)                  //对每个灰度(从0到255)计算一次分割后的类间方差sb
            {
                n1 
+= pixelNum[k];                //n1为在当前阈值遍前景图象的点数
                if (n1 == 0) { continue; }            //没有分出前景后景
                n2 = n - n1;                        //n2为背景图象的点数
                if (n2 == 0) { break; }               //n2为0表示全部都是后景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环
                csum += (double)k * pixelNum[k];    //前景的“灰度的值*其点数”的总和
                m1 = csum / n1;                     //m1为前景的平均灰度
                m2 = (sum - csum) / n2;               //m2为背景的平均灰度
                sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2);   //sb为类间方差
                if (sb > fmax)                  //如果算出的类间方差大于前一次算出的类间方差
                {
                    fmax 
= sb;                    //fmax始终为最大类间方差(otsu)
                    threshValue = k;              //取最大类间方差时对应的灰度的k就是最佳阈值
                }
            }
            
return threshValue;
        }

    2、如何去除干扰点/干扰线
    2.1 干扰点/干扰线的特征分析
    现在网上的大多数的验证码都是加了干扰的,一般分为干扰点和干扰线,如下图。标用1、2、3的分别为点、线、字符。

   去干扰,一般是逐点分析,这三种情况下,每一点及周边8个点的情况都不一样(分别为1点,3点,8点),这是一种干扰信息的粒度比字符的粒度小的典型情况。现在就可以动手编写去杂代码了。
   
    2.2 根据周边有效点数去噪函数

        /// <summary>
        
///  去掉杂点(适合杂点/杂线粗为1)
        
/// </summary>
        
/// <param name="dgGrayValue">背前景灰色界限</param>
        
/// <returns></returns>
        public void ClearNoise(int dgGrayValue, int MaxNearPoints)
        {
            Color piexl;
            
int nearDots = 0;
            
int XSpan, YSpan, tmpX, tmpY;
            
//逐点判断
            for (int i = 0; i < bmpobj.Width; i++)
                
for (int j = 0; j < bmpobj.Height; j++)
                {
                    piexl 
= bmpobj.GetPixel(i, j);
                    
if (piexl.R < dgGrayValue)
                    {
                        nearDots 
= 0;
                        
//判断周围8个点是否全为空
                        if (i == 0 || i == bmpobj.Width - 1 || j == 0 || j == bmpobj.Height - 1)  //边框全去掉
                        {
                            bmpobj.SetPixel(i, j, Color.FromArgb(
255255255));
                        }
                        
else
                        {
                            
if (bmpobj.GetPixel(i - 1, j - 1).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i, j - 1).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i + 1, j - 1).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i - 1, j).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i + 1, j).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i - 1, j + 1).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i, j + 1).R < dgGrayValue) nearDots++;
                            
if (bmpobj.GetPixel(i + 1, j + 1).R < dgGrayValue) nearDots++;
                        }

                        
if (nearDots < MaxNearPoints)
                            bmpobj.SetPixel(i, j, Color.FromArgb(
255255255));   //去掉单点 && 粗细小3邻边点
                    }
                    
else  //背景
                        bmpobj.SetPixel(i, j, Color.FromArgb(255255255));
                }
        }

    2.3 滤波算法去噪函数
     图像预处理中有多种滤波算法,其原理与方法分别为
     1) 中值滤波
    它通过从图像中的某个采样窗口取出奇数个数据进行排序得到的结果。顾名思义,所谓中值就是窗口中奇数个数据按大小顺序排列后处于中心位置的那个数。中值滤波以窗口的中值作为处理结果。
    实现起来很简单
    1:先对窗口排序
    2:用排序后的中值取代要处理的数据即可
    注意事项:
    1:注意图像边缘数据的处理
    2:对于不同的目的选用不同的窗体,一般有3×3,5×5等等

        /// <summary>
        
/// 3×3中值滤波除杂,yuanbao,2007.10
        
/// </summary>
        
/// <param name="dgGrayValue"></param>
        public void ClearNoise(int dgGrayValue)
        {
            
int x, y;
            
byte[] p = new byte[9]; //最小处理窗口3*3
            byte s;
            
//byte[] lpTemp=new BYTE[nByteWidth*nHeight];
            int i, j;

            
//--!!!!!!!!!!!!!!下面开始窗口为3×3中值滤波!!!!!!!!!!!!!!!!
            for (y = 1; y < bmpobj.Height - 1; y++//--第一行和最后一行无法取窗口
            {
                
for (x = 1; x < bmpobj.Width - 1; x++)
                {
                    
//取9个点的值
                    p[0= bmpobj.GetPixel(x - 1, y - 1).R;
                    p[
1= bmpobj.GetPixel(x, y - 1).R;
                    p[
2= bmpobj.GetPixel(x + 1, y - 1).R;
                    p[
3= bmpobj.GetPixel(x - 1, y).R;
                    p[
4= bmpobj.GetPixel(x, y).R;
                    p[
5= bmpobj.GetPixel(x + 1, y).R;
                    p[
6= bmpobj.GetPixel(x - 1, y + 1).R;
                    p[
7= bmpobj.GetPixel(x, y + 1).R;
                    p[
8= bmpobj.GetPixel(x + 1, y + 1).R;
                    
//计算中值
                    for (j = 0; j < 5; j++)
                    {
                        
for (i = j + 1; i < 9; i++)
                        {
                            
if (p[j] > p[i])
                            {
                                s 
= p[j];
                                p[j] 
= p[i];
                                p[i] 
= s;
                            }
                        }
                    }
              
//      if (bmpobj.GetPixel(x, y).R < dgGrayValue)
                        bmpobj.SetPixel(x, y, Color.FromArgb(p[4], p[4], p[4]));    //给有效值付中值
                }
            }
        }
   经过实际运行证实,中值滤波能有效去除图像中的噪声点,特别是在一片连续变化缓和的区域中(比如人的衣服,皮肤),几乎100%去除灰度突变点(可以认为 是噪声点),也因为如此,中值滤波不适合用在一些细节多,如细节点,细节线多的图像中,因为细节点有可能被当成噪声点去除。
 
 

    中值滤波的窗口还可以有多种形状,上面程序选择的是矩形(容易计算),其实窗口还可以是菱形,圆形,十字形等等,不同的窗口形状有不同的滤波效果,对有缓慢且有较长轮廓线的物体适合用矩形或者原型窗口,对于有尖顶角物体的图像适合采用十字形窗口。
    中值滤波可以进行线性组合,不同窗口形状的滤波器可以线性组合
    改进中值滤波方法:
    对一些内容复杂的图像,可以使用复合型中值滤波。如, 中值滤波线性组合、高阶中值滤波组合、加权中值滤波以及迭代中值滤波等。
    中值滤波的线性组合是将几种窗口尺寸大小和形状不同的中值滤波器复合使用,只要各窗口都与中心对称,滤波输出可保持几个方向上的边缘跳变,而且跳变幅度可调节。
    高阶中值滤波组合可以使输入图像中任意方向的细线条保持不变。
    为了在一定的条件下尽可能去除噪声,又有效保持图像细节,可以对中值滤波器参数进行修正, 如加权中值滤波, 也就是对输入窗口进行加权。
    也可以是对中值滤波器的使用方法进行变化, 保证滤波的效果, 还可以和其他滤波器联合使用。
 
    2).均值滤波(模糊算法)
    均值滤波是典型的线性滤波算法,它是指在图像上对待处理的像素给一个模板,该模板包括了其周围的临近像素。将模板中的全体像素的均值来代替原来的像素值的方法。

    3)维纳(Wiener)滤波
    维纳(Wiener)滤波是对退化图像进行恢复处理的另一种常用算法,是一种有约束的恢复处理方法,其采用的维纳滤波器是一种最小均方误差滤波器,其数学形式比较复杂:
    F(u,v)=[(1/H(u,v))*(|H(u,v)|2)/(|H(u,v)|2+s*[Sn(u,v)/Sf(u,v)])]*G(u,v)
& nbsp;   当s为1时,上式就是普通的维纳滤波;如果s为变量,则为参数维纳滤波,如果没有噪声干扰,即Sn (u,v)=0时,上式实际就是前面的逆滤波。从其数学形式可以看出:维纳滤波比逆滤波在对噪声的处理方面要强一些。以上只是理论上的数学形式,在进行实 际处理时,往往不知道噪声函数Sn(u,v)和Sf(u,v)的分布情况,因此在实际应用时多用下式进行近似处理:
    F(u,v)=[(1/H(u,v))* (|H(u,v)|2)/(|H(u,v)|2+K)]*G(u,v)
    其中K是一个预先设定的常数。
【报错】open /var/lib/docker/tmp/docker-import-863402796/bin/json: no such file or directory 然后,通过docker images可以看到镜像已经加载进来了。然后,通过docker images可以看到镜像已经加载进来了。 阅读详情

相关推荐

【光子 AI 】应用 LangGraph 的核心模型和算法原理,完整实现一个极简版的 Agent 开发框架源代码,并给出具体的应用测试实际项目案例

下面给出一个“极简版 LangGraph 风格 Agent 框架”的完整可运行实现:用 有向图 + 状态(State) + 节(Node) + 条件路由(Conditional Edge) + 循环(Loop) + Checkpoint 这一套核心模型/算法,把 Agent 组织成可编排、可测试的状态机工作流(这正是 LangGraph 的核心抽象之一:以 StateGraph 组织节,节读写共享状态,边做路由与循环,并支持持久化/回放)。 参考概念来源:LangGraph 官方文档对 “StateG

AI天才研究院 236

C#图像平滑与(声模型、均值滤波与中值滤波、灰度形态学滤波、小波变换、高斯低通滤波、统计滤波)

C#语言、VS2005,包括声模型、均值滤波与中值滤波、灰度形态学滤波、小波变换、高斯低通滤波、统计滤波

C#图像平滑与声模型、均值滤波与中值滤波、灰度形态学滤波、小波变换、高斯低通滤波、统计滤波)

C#语言、VS2005,包括声模型、均值滤波与中值滤波、灰度形态学滤波、小波变换、高斯低通滤波、统计滤波

7x7x7x7x7任意入口在数据加密中的实际应用

具体来说,每个维度的声通过特定的算法组合,最终生成一个固定长度的密钥。这种多维声叠加的方式确保了密钥的高熵值,从而大大降低了被破解的可能性。在开发过程中,最大的挑战是如何确保声源的真正随机性。最近,我尝试利用7x7x7x7x7任意入口的特性开发了一个数据加密工具,通过生成高随机性的密钥来增强数据的安全性。7x7x7x7x7任意入口是一种多维度的随机数生成机制,通过多个维度的声叠加,可以产生高度随机的输出。这种特性非常适合用于加密密钥的生成,因为密钥的随机性直接决定了加密算法的安全性。

SunstoneLion34的博客 2万+

初学者指南:理解7x7x7x7x7任意入口的基本概念

简单来说,7x7x7x7x7任意入口是一种多维数据处理的结构。这里的“7x7x7x7x7”代表五个维度的数组或矩阵,每个维度有7个元素。而“任意入口”指的是在这个多维结构中,可以随机或按需访问特定数据的方式。

CyanWave34的博客 9万+

2021-07-13-P3187 [HNOI2007]最小矩形覆盖(凸包,旋转卡壳,凸包最小矩形覆盖--求面积及各

传送门 题意: 给定一些的坐标,要求求能够覆盖所有的最小面积的矩形,输出所求矩形的面积和四个顶坐标。 3≤n≤500003\le n\le 500003≤n≤50000 输入n及n个 输出面积及四个坐标(按一定顺序,不用纠结) 题解: 先求凸包,然后再旋转卡壳 旋转卡壳具体操作:枚举,然后卡三个(怎么卡?建议自己推) 收获: 除了熟悉了凸包和旋转卡壳之外,还学到了很多有用的新操作,比如到直线的距离,到直线的投影,过一的平行线 以及线的倾斜角,atan ,atan2等。 学的新东

I_have_a_world的博客 2万+

C#实现卡尔曼滤波器(简易版)

基于.Net的C#实现卡尔曼滤波

mingzhi_wu的博客 7139

AI如何解析7x7x7x7x7任意入口的数学模式

通过AI辅助开发,我们能够更高效地分析和解决复杂的数学问题。7x7x7x7x7入口的模式识别只是一个例子,似的思路可以推广到其他高维数据分析任务中。如果你对这问题感兴趣,可以试试在InsCode(快马)平台上快速实现这个项目。平台内置了AI模型和代码编辑器,一键部署功能让整个流程更加顺畅。实际操作中,我发现平台的响应速度很快,尤其是处理大数据量时,numpy和AI模型的结合让计算变得非常高效。如果你也是开发者,不妨试试看!

EmeraldEagle36的博客 9653

图像处理(Image Processing) ---------- 图像滤波器 () (C#实现)

讲到图像处理的滤波器,就不得不先提图像中的低频分量和高频分量: 图像的频率代表了,图像颜色变化的剧烈程度。 低频分量:一幅图中,颜色变化缓慢的部分就叫做低频部分。通常低频是描述图像的主要部分,就像人的脸。 高频分量:一幅图中,颜色变化剧烈的部分就叫做高频部分。通常高频是描述图像的边缘、细节或者是声,就像人脸的轮廓,还有脸上的痘。   平滑空间滤波器: 均值滤波器(Averaging ...

英俊强健的博客 3902

【❗JS奇技淫巧❗】JavaScript:截取DataURL中的base64字符串

图片中的src是从dataURL里赋值过的: "jpgbase64":"data:application/octet-stream;base64,/9j/4Q6PIHsic2VpaW5mbyI6eyJpcGMiOnsiaXAiOlsxMCw2Nyw4Miw5M10sImFsZyI6OSwiZW5jYmlnIjowLCJwZXJjZmciOnsicGVyZGV0dHlwZSI6MCwiZmFjZW91dG1vZGUiOjAsImZhY2ViZXN0bnVtIjowfSwidmVoY2ZnIj...

谁吃薄荷糖 30万+

基于STM32的温湿度和烟雾检测.zip

stm32f103c8t6单片机为核心,设计一套基于wifi网络的温湿度和烟雾值检测。该系统以wifi通信为基础、能通过无线通信技术实时监控家居的温湿度状态,烟雾值。并能自由控制家居的电器的开关操作。硬件电路1.温度低于15度  亮一盏led模拟升高室温 高于15度2.烟雾浓度高于一定的值 蜂鸣器持响持闪烁led灯(红色) 并发送报警消息到app 低于一定值 一定时间后取消报警  3.采集到的信息要在显示屏显示App端1. 数据实时显示 报警消息要收的到2. 控制led灯等资料包括1、APP2、相关元件手册3、原理图和PCB图4、程序5、元件清单6、实物图

上一篇: 4句话来概括四大名著哈哈
下一篇: IIS5、IIS6、IIS7的ASP.net 请求处理过程比较
zfrong
博客等级 码龄19年 7122粉丝 43原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值