2012-09-17 25 views
1

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

大家好,我試圖此驗證碼轉換爲「黑與白」(二值化)圖像,其中的人物是白色的,所有的剩餘(背景下,線,隨機圖片)是黑色。

鏈接到驗證碼可以被找到here。刷新會給你另一個驗證碼。

原因:

我知道大多數人認爲這是錯誤惹的驗證碼所以我在這裏捍衛自己。這將僅用於知識/自我挑戰。沒有其他用途計劃這些圖像。

問題:

後研究這些圖像了一段時間,我想通了,一個很好的形式給出。將更換的顏色:「白色和黃色」到「Color.Black」,和所有其他顏色應該替換爲「Color.White」。

在此之後,我只是「反轉」的顏色,引導我到我想要的輸出。

代碼示例:

在這段代碼中,我試圖取代每個圖像的顏色「黑」的天藍色像素。

 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 Framework,我用它來減少顏色,但它根本不工作,結果不是我所期望的。

我可以在這裏做什麼,以便正確地二值化此圖像?

在此先感謝,

Marcello Lins。

+0

的CAPTCHA我看到含有黃色「Q」和「C」和一個黑色的「Q」,也是一種白色的「W」和一個白色的「C」你方法會使黑色消失。 – LSerni

+0

他們不會消失,因爲背景是灰色的,從不黑。 我想讓所有的角色都具有相同的顏色,並且由於角色的顏色只能是「白色,黃色和黑色」,所以我最終會將所有角色都看作黑色,而其他所有角色都會被視爲背景。 –

回答

1

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

的近似方法是:

  • 刪除所有灰度(通道彼此小於5%不同的),其具有低於220的信道的平均灰色。這可以消除灰色背景中的細光線以及大部分振鈴(JPEG)僞影。
  • 替換其中紅色,綠色或藍色通道高於25%的所有像素兩個其他兩個灰色通道。這需要照顧紅色,綠色和藍色以及他們大部分的響鈴人工製品。
  • 運行一個簡單的去斑點去除由五個灰度包圍的所有非nrayray像素,並且在20%以內沒有其他相同顏色的像素。

在這個過程結束時,背景全部是灰色的,剩下的所有nongray像素都是字符。

一些有用的功能:

// 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. 
+0

只需重新檢查一下,你是否測試過它? –

+0

有幾個CAPTCHA,是的。但是,您可能想要嘗試這些閾值 - 例如「220」。我認爲這可能會進一步提高。另外,這取決於稍後使用的OCR:我停止了五個灰色的去斑,否則它會削減角色的灰度。可能是四個或六個,會給出更好的最終結果。 – LSerni

+0

@Iserni非常感謝。我會盡快試一試:) –