簡體   English   中英

如何在C#位圖中替換相同顏色的色調變化?

[英]How do i replace tone variations of the same color in a C# Bitmap?

適用范圍

大家好,我正在嘗試將此驗證碼轉換為“黑白”(二進制化)圖像,其中字符為白色,其余所有字符(背景,線條,隨機圖片)為黑色。

驗證碼的鏈接可以在這里找到。 刷新會給您另一個驗證碼。

原因:

我知道大多數人都認為弄錯驗證碼是錯誤的,所以我在這里為自己辯護。 這將僅用於知識/自我挑戰。 這些圖像沒有其他用途。

問題:

在研究了這些圖像一段時間之后,我發現一個很好的方法是將顏色從“白色和黃色”替換為“ Color.Black”,並將所有其他顏色替換為“ Color.White”。

在此之后,我只需“反轉”顏色,即可將其引導至所需的輸出。

代碼示例:

在這段代碼中,我試圖將每張圖片的顏色“黑色”替換為SkyBlue Pixel。

        WebRequests wr = new WebRequests(); // My class to handle WebRequests
        Bitmap bmp;
        string url = "http://www.fazenda.rj.gov.br/projetoCPS/codigoImagem";

        bmp = wr.GetBitmap (url);

        for (int i = 1; i < bmp.Height ; i++)
        {
            for (int j = 1 ; j < bmp.Width ; j++)
            {
                if (bmp.GetPixel(j,i).Equals(Color.Black))
                {
                    bmp.SetPixel(j,i, Color.SkyBlue);
                }
            }
        }

該代碼根本不起作用,我不確定為什么,但是在此示例中沒有像素被替換。

題:

我該如何工作? 我在這里想念什么?

另外,對我來說,理想的方案是將該圖像的調色板“減少”為“基本”顏色,這將使我的工作更加輕松。

我已經嘗試過AForge框架 ,我正在使用它來減少顏色,但是它根本不起作用,結果不是我所期望的。

為了正確地對該圖像進行二值化,我該怎么辦?

提前致謝,

馬塞洛·林斯(Marcello Lins)。

您的算法不起作用的原因是您正在尋找完全匹配的內容。 但是,由於JPEG壓縮偽像,圖像中的黑色並不是真正的黑色。 在我加載的三個CAPTCHAS中,甚至沒有一個黑色(0、0、0)像素。 最接近的值是(0,0,4),看起來是黑色,但不是。

一種近似的方法是:

  • 移除通道平均值低於220的所有灰色(通道彼此之間的差異小於5%)。 這可以消除淺灰色的線條以及灰色背景上的許多振鈴(JPEG)偽影。
  • 將紅色,綠色或藍色通道比其他兩個通道高25%以上的所有像素替換為灰色。 這可以照顧到紅色,綠色和藍色以及它們大部分的響聲。
  • 運行一個簡單的去斑點,以去除所有非灰色像素(被五個灰色包圍,並且在20%內沒有其他相同顏色的像素)。

在此過程結束時,背景均為灰色,剩下的所有非灰色像素均為字符。

一些有用的功能:

// Very basic (and CIE-incorrect) check
public static int isGray(Color c)
{
    if (Math.Abs(c.R - c.G) > 5 * 2.55) return 0; // Not gray. R and G too different
    if (Math.Abs(c.R - c.B) > 5 * 2.55) return 0;
    if (Math.Abs(c.G - c.B) > 5 * 2.55) return 0;
    return 1;
}

// the blind man's test for shading :-)
public static int isShadeOfRed(Color c)
{
    if (4*c.R < 5*c.G) return 0; // Red not strong enough in respect to green
    if (4*c.R < 5*c.B) return 0; // Red not strong enough in respect to blue
    return 1; // Red is stronger enough than green and blue to be called "shade of red"
}

// (shades of green and blue left as an exercise)

// Very basic (and CIE-incorrect) check
public static int areSameColor(Color a, Color b)
{
    if (Math.Abs(a.R - b.R) > 5 * 2.55) return 0;
    if (Math.Abs(a.G - b.G) > 5 * 2.55) return 0; 
    if (Math.Abs(a.B - b.B) > 5 * 2.55) return 0;
    return 1; // "more or less" the same color
}

// This is more or less pseudo code...
public static int isNoise(int x, int y)
{
    if ((x < 1) || (y < 1)) return 0; // or maybe "return 1"
    if ((x+1 >= bmp.Width)||(y+1 >= bmp.Height)) return 0;
    pix = bmp.GetPixel(x,y);
    for (i = -1; i <= 1; i++)
        for (j = -1; j <= 1; j++)
        {
            if ((i == 0) && (j == 0)) continue;
            test = bmp.GetPixel(x+i, y+j);
            if (isGray(test)) grays++;
            if (isSameColor(pix, test)) same++;
        }
    // Pixel surrounded by grays, and has no neighbours of the same colour
    // (who knows, maybe we could skip gray calculation and check altogether?)
    // is noise.
    if ((grays == 5) && (same == 0))
       return 1;
    return 0;
}

// NOTE: do not immediately set to gray pixels found to be noise, for their neighbours
// will be calculated using the new gray pixel. Damage to image might result.
// Use a copy of bmp instead.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM