Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何修复书页的暗显图像_C#_Image Processing - Fatal编程技术网

C# 如何修复书页的暗显图像

C# 如何修复书页的暗显图像,c#,image-processing,C#,Image Processing,我有1000张书页的图片,它的文字和这张一样暗淡 现在我试图修复它,以便更清晰地阅读,我使用此代码 private Bitmap repairImage(Bitmap bmp) { Color cc=Color.FromArgb(255, 251, 251, 251); for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Heig

我有1000张书页的图片,它的文字和这张一样暗淡
现在我试图修复它,以便更清晰地阅读,我使用此代码

 private Bitmap repairImage(Bitmap bmp)
    {
        Color cc=Color.FromArgb(255, 251, 251, 251);
        for (int x = 0; x < bmp.Width; x++)
        {
            for (int y = 0; y < bmp.Height; y++)
            {
                if (bmp.GetPixel(x, y).R>238)
                {
                    bmp.SetPixel(x, y, Color.White);
                }
                else
                {
                    bmp.SetPixel(x, y, Color.Black);
                }
            }
        }
       return bmp;
    }
私有位图图像(位图bmp)
{
Color cc=Color.FromArgb(255,251,251,251);
对于(int x=0;x238)
{
bmp.SetPixel(x,y,Color.White);
}
其他的
{
bmp.SetPixel(x,y,Color.Black);
}
}
}
返回bmp;
}
由于图像尺寸为1168 x 1807,因此需要花费大量时间来完成修复,它正好循环2110576个循环。
还有别的办法解决这个问题吗?谢谢。

我使用这个(C++)代码:

void picture::enhance_range()
    {
    int i,x,y,a0[4],min[4],max,n,c0,c1,q,c;
    if (xs<1) return;
    if (ys<1) return;

    n=0;    // dimensions to interpolate
    if (pf==_pf_s   ) { n=1; c0=0; c1=127*3; }
    if (pf==_pf_u   ) { n=1; c0=0; c1=255*3; }
    if (pf==_pf_ss  ) { n=2; c0=0; c1=32767; }
    if (pf==_pf_uu  ) { n=2; c0=0; c1=65535; }
    if (pf==_pf_rgba) { n=4; c0=0; c1=  255; } // this is your image pixel format so ignore the other pf statements

    // find min,max intensities
    dec_color(a0,p[0][0],pf);
    for (i=0;i<n;i++) min[i]=a0[i]; max=0;
    for (y=0;y<ys;y++)
     for (x=0;x<xs;x++)
        {
        dec_color(a0,p[y][x],pf); // this just unpack pixel color p[][] to a0[4]={r,g,b,a}
        for (q=0,i=0;i<n;i++)
            {
            c=a0[i]; if (c<0) c=-c;
            if (min[i]>c) min[i]=c;
            if (max<c) max=c;
            }
        }
    // change dynamic range to max
    for (y=0;y<ys;y++)
     for (x=0;x<xs;x++)
        {
        dec_color(a0,p[y][x],pf);
        for (i=0;i<n;i++) a0[i]=c0+(((a0[i]-min[i])*(c1-c0))/(max-min[i]+1));
//      for (i=0;i<n;i++) if (a0[i]<c0) a0[i]=c0; // clamp if needed
//      for (i=0;i<n;i++) if (a0[i]>c1) a0[i]=c1; // clamp if needed
        enc_color(a0,p[y][x],pf); // this just pack a0[4]={r,g,b,a} to pixel color p[][]
        }
    }
因此,如果您选取每个像素并重新缩放到最大值,则需要执行以下操作:

color=(color-min)*255/(max-min);
对于图像的每个像素,仅此而已

[Notes]

正如@RosaGronchi提到的,由于使用了
getpixel,您当前的方法速度很慢,setpixel
使用扫描线(应该快几千倍)

您的方法的另一个缺点是,您只需对图像进行二值化,就可以消除所有渲染的文本抗锯齿…

我使用以下(C++)代码:

void picture::enhance_range()
    {
    int i,x,y,a0[4],min[4],max,n,c0,c1,q,c;
    if (xs<1) return;
    if (ys<1) return;

    n=0;    // dimensions to interpolate
    if (pf==_pf_s   ) { n=1; c0=0; c1=127*3; }
    if (pf==_pf_u   ) { n=1; c0=0; c1=255*3; }
    if (pf==_pf_ss  ) { n=2; c0=0; c1=32767; }
    if (pf==_pf_uu  ) { n=2; c0=0; c1=65535; }
    if (pf==_pf_rgba) { n=4; c0=0; c1=  255; } // this is your image pixel format so ignore the other pf statements

    // find min,max intensities
    dec_color(a0,p[0][0],pf);
    for (i=0;i<n;i++) min[i]=a0[i]; max=0;
    for (y=0;y<ys;y++)
     for (x=0;x<xs;x++)
        {
        dec_color(a0,p[y][x],pf); // this just unpack pixel color p[][] to a0[4]={r,g,b,a}
        for (q=0,i=0;i<n;i++)
            {
            c=a0[i]; if (c<0) c=-c;
            if (min[i]>c) min[i]=c;
            if (max<c) max=c;
            }
        }
    // change dynamic range to max
    for (y=0;y<ys;y++)
     for (x=0;x<xs;x++)
        {
        dec_color(a0,p[y][x],pf);
        for (i=0;i<n;i++) a0[i]=c0+(((a0[i]-min[i])*(c1-c0))/(max-min[i]+1));
//      for (i=0;i<n;i++) if (a0[i]<c0) a0[i]=c0; // clamp if needed
//      for (i=0;i<n;i++) if (a0[i]>c1) a0[i]=c1; // clamp if needed
        enc_color(a0,p[y][x],pf); // this just pack a0[4]={r,g,b,a} to pixel color p[][]
        }
    }
因此,如果您选取每个像素并重新缩放到最大值,则需要执行以下操作:

color=(color-min)*255/(max-min);
对于图像的每个像素,仅此而已

[Notes]

正如@RosaGronchi提到的,由于使用了
getpixel,您当前的方法速度很慢,setpixel
使用扫描线(应该快几千倍)


您的方法的另一个缺点是,您只需对图像进行二值化,从而使所有渲染的文本消除混叠…

我所能想到的最好方法是使用内置类来更改图像的Gamma对比度

以下是
Gamma=6.27
对比度=+1.04
的结果:

以下是我使用的代码:

using System.Drawing.Imaging;
..

public static Bitmap ApplyGamma(Bitmap bmp0, float gamma, float contrast)
{

    Bitmap bmp1 = new Bitmap(bmp0.Width, bmp0.Height);
    using (Graphics g = Graphics.FromImage(bmp1))
    {
        ColorMatrix colorMatrix = new ColorMatrix(new float[][] 
                {
                    new float[] {contrast, 0, 0, 0, 0},
                    new float[] {0,contrast, 0, 0, 0},
                    new float[] {0, 0, contrast, 0, 0},
                    new float[] {0, 0, 0, 1, 0},
                    new float[] {0, 0, 0, 0, 1}
                });


        ImageAttributes attributes = new ImageAttributes();
        attributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default,
                                               ColorAdjustType.Bitmap);
        attributes.SetGamma(gamma, ColorAdjustType.Bitmap);
        g.DrawImage(bmp0, new Rectangle(0, 0, bmp0.Width, bmp0.Height),
                    0, 0, bmp0.Width, bmp0.Height, GraphicsUnit.Pixel, attributes);
    }
    return bmp1;
}
该函数使用两个变量和两个
轨迹栏
,以及两个
标签

float gamma = 1f ;
float contrast = 1f;

private void trackBar1_Scroll(object sender, EventArgs e)
{
    gamma = 1f * trackBar1.Value / 100f;
    label1.Text = gamma.ToString("#0.00");
    pictureBox1.Image = ApplyGamma(originalImage, gamma, contrast);
}


private void trackBar2_Scroll(object sender, EventArgs e)
{
    contrast = 1f * trackBar2.Value / 1000f;
    label2.Text = contrast.ToString("#0.00");
    pictureBox1.Image = ApplyGamma(originalImage, gamma, contrast);
}

请注意,我正在泄漏位图;只是为了测试;-)

我能想到的最好方法是使用内置类来更改图像的Gamma对比度

以下是
Gamma=6.27
对比度=+1.04
的结果:

以下是我使用的代码:

using System.Drawing.Imaging;
..

public static Bitmap ApplyGamma(Bitmap bmp0, float gamma, float contrast)
{

    Bitmap bmp1 = new Bitmap(bmp0.Width, bmp0.Height);
    using (Graphics g = Graphics.FromImage(bmp1))
    {
        ColorMatrix colorMatrix = new ColorMatrix(new float[][] 
                {
                    new float[] {contrast, 0, 0, 0, 0},
                    new float[] {0,contrast, 0, 0, 0},
                    new float[] {0, 0, contrast, 0, 0},
                    new float[] {0, 0, 0, 1, 0},
                    new float[] {0, 0, 0, 0, 1}
                });


        ImageAttributes attributes = new ImageAttributes();
        attributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default,
                                               ColorAdjustType.Bitmap);
        attributes.SetGamma(gamma, ColorAdjustType.Bitmap);
        g.DrawImage(bmp0, new Rectangle(0, 0, bmp0.Width, bmp0.Height),
                    0, 0, bmp0.Width, bmp0.Height, GraphicsUnit.Pixel, attributes);
    }
    return bmp1;
}
该函数使用两个变量和两个
轨迹栏
,以及两个
标签

float gamma = 1f ;
float contrast = 1f;

private void trackBar1_Scroll(object sender, EventArgs e)
{
    gamma = 1f * trackBar1.Value / 100f;
    label1.Text = gamma.ToString("#0.00");
    pictureBox1.Image = ApplyGamma(originalImage, gamma, contrast);
}


private void trackBar2_Scroll(object sender, EventArgs e)
{
    contrast = 1f * trackBar2.Value / 1000f;
    label2.Text = contrast.ToString("#0.00");
    pictureBox1.Image = ApplyGamma(originalImage, gamma, contrast);
}

请注意,我正在泄漏位图;只是为了测试;-)

看这里:(避免对每个像素使用GetPixel()和SetPixel())查找gamma和ColorMatrix!请参见,特别是指南的链接!看这里:(避免对每个像素使用GetPixel()和SetPixel())查找gamma和ColorMatrix!请参见,特别是指南的链接!对我来说,这应该快几千倍,听起来相当乐观。@TaW如果编码正确,一点也不。。。每个
setpixel
getpixel
都会调用许多GDI调用,检查边界、像素格式、覆盖以及更多。。。
ScanLine
属性也会执行此操作,但每行仅执行一次,如果记住,则每幅图像每行仅执行一次/resize,并且可以在。。。在重像素访问上,通常的速度提升约为
10000x
次(例如在SW 3D渲染或填充算法上)。。。但必须正确编码…上次我压缩锁位和get/setPixel的速度快了20倍。很多,但决不是几千。。但这和你的代码不一样,我想。@Taw这取决于你实际使用了多少
getpiel
setpixel
而不是直接像素访问。。。与其他GDI呼叫的数量相反。如果你所指的
getpixel
setpixel
不是GDI,那就完全是另一个话题了。我比较了使用C#angainst LockBits的GDI+Get/setpixel。这应该快几千倍,这对我来说听起来相当乐观。@TaW如果编码正确,一点也不。。。每个
setpixel
getpixel
都会调用许多GDI调用,检查边界、像素格式、覆盖以及更多。。。
ScanLine
属性也会执行此操作,但每行仅执行一次,如果记住,则每幅图像每行仅执行一次/resize,并且可以在。。。在重像素访问上,通常的速度提升约为
10000x
次(例如在SW 3D渲染或填充算法上)。。。但必须正确编码…上次我压缩锁位和get/setPixel的速度快了20倍。很多,但决不是几千。。但这和你的代码不一样,我想。@Taw这取决于你实际使用了多少
getpiel
setpixel
而不是直接像素访问。。。与其他GDI呼叫的数量相反。如果您所指的
getpixel
setpixel
不是GDI,那么这完全是另一个话题。我比较了使用GDI+Get/setpixel from C#angainst LockBits。