文号
t18018
阅读
7198
回复
19
收藏
4
【class】C#指针二值化代码
2009/07/29
IP:广东
用指针那是相当的快。。相当的爽。。。普通验证码基本1ms之内解决掉

这里暂时是RGB2L法,要RGB2H的改一下就好
编译好的类


attachment icon Binary.rar 2.53KB RAR 33次下载


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;

namespace Binary
{
    public class CSunsafe
    {
        private System.Drawing.Bitmap curBitmap;
        private int[,] pic;

        public void File_Init(string sFilename)
        {
            if (sFilename != null)
            {
                curBitmap = (Bitmap)Image.FromFile(sFilename);
            }
        }

        public void BMP_Init(Bitmap BMP)
        {
            if (BMP != null)
            {
                curBitmap = BMP;
            }
        }

        private double Max(double a, double b)
        {
            if (a > b)
            {
                return a;
            }
            return b;
        }

        private double Min(double a, double b)
        {
            if (a < b)
            {
                return a;
            }
            return b;
        }

        private double RGB2H(double r, double g, double b)
        {
            double h;
            r /= 255.0;
            g /= 255.0;
            b /= 255.0;
            double mi = this.Min(r, this.Min(g, b));
            double ma = this.Max(r, this.Max(g, b));
            h = 0;
            double del_max = ma - mi;
            if (del_max == 0.0)
            {
                return 0.0;
            }
            double del_r = ((ma - (r / 6.0)) + (del_max / 2.0)) / del_max;
            double del_g = ((ma - (g / 6.0)) + (del_max / 2.0)) / del_max;
            double del_b = ((ma - (b / 6.0)) + (del_max / 2.0)) / del_max;

            if (r == ma)
            {
                h = del_b - del_g;
            }
            else if (g == ma)
            {
                h = (1.0/3.0 + del_r) - del_b;
            }
            else if (b == ma)
            {
                h = (2.0/3.0 + del_g) - del_r;
            }
            if (h < 0.0)
            {
                h++;
            }
            if (h > 1.0)
            {
                h--;
            }
            return h;
        }


        private double RGB2L(double r, double g, double b)
        {
            r /= 255.0;
            g /= 255.0;
            b /= 255.0;
            double mi = this.Min(r, this.Min(g, b));
            return ((this.Max(r, this.Max(g, b)) + mi) / 2.0);
        }


        public int[,] Binary(double value)
        {
            if (curBitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                pic = new int [bmpData.Width,bmpData.Height];
                unsafe
                {
                    byte* ptr = (byte*)(bmpData.Scan0);
                    for (int i = 0; i < bmpData.Height; i++)
                    {
                        for (int j = 0; j < bmpData.Width; j++)
                        {
                            if (RGB2L(ptr[2], ptr[1], ptr[0]) < value)
                            {
                                pic[j, i] = 1;
                            }
                            else
                            {
                                pic[j, i] = 0;
                            }
                            
                            ptr += 3;
                        }
                        ptr += bmpData.Stride - bmpData.Width * 3;
                    }
                }
                curBitmap.UnlockBits(bmpData);
                return pic;
            }
            else
            {
                return null;
            }
        }
    }
}


要编译本代码请允许不安全代码 如下图所示

unsafe.png


Binary.img.png
+1000
科创币
delete
2009/07/29
试试评个分
93°作者
17年6个月前IP:未同步
133241
1楼
最近爱上C#了 。。爱上C#了……C#…… 。。。。
引用
评论
17年6个月前IP:未同步
133243
2楼
算法很恶心(或者说我没看懂。。。有可能的)

提出二值化算法:

RGB,阈值为y
输出为gray


alpha = 3*y

if R+G+B<alpha then return 1
(如果不是,自然就是0了,不用加一句else return 0
引用
评论
17年6个月前IP:未同步
133245
3楼
RGB2H是把RGB转换为色度。
RGB2L是把RGB转换为饱和度。

chia的思路有点类似判断亮度,但实际上亮度计算R、G、B是有权重的。
引用
评论
17年6个月前IP:未同步
133246
4楼
然后就是这一段
if (RGB2L(ptr[2], ptr[1], ptr[0]) < value)
                            {
                                pic[j, i] = 1;
                            }
                            else
                            {
                                pic[j, i] = 0;
                            }
表示不满,为什么不直接这样写:
pic[j,i]=(RGB2L(ptr[2], ptr[1], ptr[0]) < value)

一定程度上说明了您的一定程度上的一定程度的问题。
引用
评论
17年6个月前IP:未同步
133247
5楼
引用第3楼qwernet于2009-07-29 16:53发表的  :
RGB2H是把RGB转换为色度。
RGB2L是把RGB转换为饱和度。

chia的思路有点类似判断亮度,但实际上亮度计算R、G、B是有权重的。

对不起弄错了。海涵……
引用
评论
17年6个月前IP:未同步
133250
6楼
这。。。
有点。。。
引用第3楼qwernet于2009-07-29 16:53发表的  :
RGB2H是把RGB转换为色度。
RGB2L是把RGB转换为饱和度。

chia的思路有点类似判断亮度,但实际上亮度计算R、G、B是有权重的。

L(Lightness)是亮度吧。。。怎么RGB2L变成饱和度了。。。
引用
评论
93°作者
17年6个月前IP:未同步
133252
7楼
引用第2楼chiataimakra于2009-07-29 16:50发表的  :
算法很恶心(或者说我没看懂。。。有可能的)

提出二值化算法:

RGB,阈值为y
.......

去试一试就知道了,这个算法在我以前的帖子里就已经发过,对于某种验证码 比如我这次做的,基本无效
引用
评论
93°作者
17年6个月前IP:未同步
133253
8楼
引用第4楼chiataimakra于2009-07-29 16:54发表的  :
然后就是这一段
if (RGB2L(ptr[2], ptr[1], ptr[0]) < value)
                            {
                                pic[j, i] = 1;
                            }
.......

请参见MSDN
引用
评论
93°作者
17年6个月前IP:未同步
133255
9楼
引用第2楼chiataimakra于2009-07-29 16:50发表的  :

(如果不是,自然就是0了,不用加一句else return 0


= = 在很大程度上表现出您对C#的不了解
还有,null不是0 。。。。如果在这个function里返回0会报错的,人家要的是二维数组。。您返回个0

null=nothing=nil=什么都没有

如果去掉return null
看
引用
评论
17年6个月前IP:未同步
133256
10楼
Re:这。。。
引用第6楼chiataimakra于2009-07-29 16:58发表的 这。。。 :
有点。。。

L(Lightness)是亮度吧。。。怎么RGB2L变成饱和度了。。。


哦,看错了。
引用
评论
93°作者
17年6个月前IP:未同步
133258
11楼
引用第2楼chiataimakra于2009-07-29 16:50发表的  :
算法很恶心(或者说我没看懂。。。有可能的)

提出二值化算法:

RGB,阈值为y
.......

参见这里https://www.kechuang.org/t/12553
引用
评论
17年6个月前IP:未同步
133260
12楼
明度、亮度
[s:94][s:94]
引用第6楼chiataimakra于2009-07-29 16:58发表的 这。。。 :
有点。。。

L(Lightness)是亮度吧。。。怎么RGB2L变成饱和度了。。。


这个其实也不叫亮度,叫明度。

这个才是亮度:0.299*R+0.587*G+0.114*B

哎,名词我都搞乱了。
引用
评论
93°作者
17年6个月前IP:未同步
133263
13楼
引自《C++ primer》

定义变量时,应该给变量赋初始值,除非确定变量用于其它意图之前会覆盖这个初值。

虽然是关于cpp的,但是所有编程语言都应该这样做,“如果不是自然就是0了”很明显是不符合编程规范的
使用C的时候就囧死你了,int i,直接出i的值的话保证囧飞你
引用
评论
93°作者
17年6个月前IP:未同步
133265
14楼
虽然说我命名极其不规范,UI极其不规范,但是我这个编程思想还是要规范的 。。。 = =
引用
评论
17年6个月前IP:未同步
133266
15楼
了解,是我脑残了,VB用多了。我知道要在前面加"!@#$@#%$! = 0"这句。。。。

另外,明度是。。。我想起来了。。。
在PS7里,HSL被变成了HSB,B=brightness

画图里面是HSL

Lab色彩空间内,L是limitude照明度。
引用
评论
93°作者
17年6个月前IP:未同步
133267
16楼
送上测试代码

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim binary_frame As New Binary.CSunsafe
        binary_frame.BMP_Init(PictureBox1.Image)
        pic = binary_frame.Binary_L(0.6)

        debug(pic, 50, 85)

    End Sub

    Public Function debug(ByVal pic(,) As Integer, ByVal width As Integer, ByVal height As Integer)
        Dim bmp As New Bitmap(width + 1, height + 1)
        Dim i, j As Integer
        For i = 0 To width
            For j = 0 To height
                If pic(i, j) = 1 Then
                    bmp.SetPixel(i, j, Color.Black)
                End If
            Next
        Next
        Dim frm As New Form
        frm.BackgroundImage = bmp
        frm.BackgroundImageLayout = ImageLayout.Center
        frm.Show()
        Return Nothing
    End Function
引用
评论
17年6个月前IP:未同步
133269
17楼
引用第15楼chiataimakra于2009-07-29 17:27发表的  :
了解,是我脑残了,VB用多了。我知道要在前面加"!@#$@#%$! = 0"这句。。。。

另外,明度是。。。我想起来了。。。
在PS7里,HSL被变成了HSB,B=brightness

.......


嗯,名称变来变去都搞不清了,咱们自己知道咋回事就行了
引用
评论
14年10个月前IP:未同步
369719
18楼
真好,谢谢
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的