2009-12-09 38 views
9

Tôi đang quét tài liệu sang hình ảnh JPG. Máy quét phải quét tất cả các trang dưới dạng màu hoặc tất cả các trang dưới dạng màu đen và trắng. Vì nhiều trang của tôi có màu, tôi phải quét tất cả các trang dưới dạng màu. Sau khi quét xong, tôi muốn kiểm tra các hình ảnh với .Net và cố gắng phát hiện những hình ảnh nào có màu đen và trắng để tôi có thể chuyển đổi những hình ảnh đó sang màu xám và lưu vào bộ nhớ.Phát hiện hình ảnh thang độ xám với .Net

Có ai biết cách phát hiện hình ảnh thang độ xám với .Net không?

Vui lòng cho tôi biết.

+1

Kiểm tra loại hình ảnh sẽ không cắt vì nó sẽ được đặt trong 24 hoặc 32 bit (vì bạn đang quét màu). Có thể bạn sẽ phải kiểm tra từng pixel; nếu R == G == B trong tất cả các pixel, đó là hình ảnh thang độ xám, nếu không nó có thể là màu. –

+1

Suy nghĩ: Mặc dù máy quét trong lý thuyết đang cung cấp R == G == B, có thể là trong quá trình nén JPEG, có thể có một số điểm ảnh mà chỉ gần như đúng? Hãy xem xét, JPEG là một thuật toán nén mất dữ liệu. Có lẽ JPEG mất một số quyền tự do với màu pixel gần đó. Nhưng tôi thú nhận, tôi không phải là một chuyên gia về JPEG. Nhưng tôi muốn biết làm thế nào nó hoạt động trước khi tôi dựa vào R == G == B. –

+0

Vâng, tôi ghét phải dựa vào chính xác r == g == b bởi vì ngay cả khi jpg không làm bất kỳ fudging (và tôi đặt cược nó), máy quét của bạn và bản gốc sẽ phải được hoàn hảo là tốt, mà tấn công tôi như không có trong nhiều trường hợp. – Beska

Trả lời

5

Thuật toán đơn giản để kiểm tra màu: Đi theo pixel ảnh theo pixel trong vòng lặp (chiều rộng và chiều cao) và kiểm tra xem liệu giá trị RGB của pixel có bằng nhau hay không. Nếu không thì hình ảnh có thông tin màu. Nếu bạn làm cho nó tất cả các cách thông qua tất cả các điểm ảnh mà không gặp phải tình trạng này, sau đó bạn có một hình ảnh quy mô màu xám.

sửa đổi với một thuật toán phức tạp hơn:

Trong rev đầu tiên của bài viết này tôi đề xuất một thuật toán đơn giản mà giả định rằng pixel là quy mô màu xám nếu RGB của mỗi điểm ảnh là những giá trị đều bình đẳng. Vì vậy, RGB của 0,0,0 hoặc 128,128,128 hoặc 230,230,230 tất cả sẽ kiểm tra như màu xám trong khi 123,90,78 sẽ không. Đơn giản.

Đây là đoạn mã kiểm tra phương sai từ màu xám. Hai phương pháp là một phần nhỏ của một quy trình phức tạp hơn nhưng phải cung cấp đủ mã thô để trợ giúp với câu hỏi ban đầu.

/// <summary> 
/// This function accepts a bitmap and then performs a delta 
/// comparison on all the pixels to find the highest delta 
/// color in the image. This calculation only works for images 
/// which have a field of similar color and some grayscale or 
/// near-grayscale outlines. The result ought to be that the 
/// calculated color is a sample of the "field". From this we 
/// can infer which color in the image actualy represents a 
/// contiguous field in which we're interested. 
/// See the documentation of GetRgbDelta for more information. 
/// </summary> 
/// <param name="bmp">A bitmap for sampling</param> 
/// <returns>The highest delta color</returns> 
public static Color CalculateColorKey(Bitmap bmp) 
{ 
    Color keyColor = Color.Empty; 
    int highestRgbDelta = 0; 

    for (int x = 0; x < bmp.Width; x++) 
    { 
     for (int y = 0; y < bmp.Height; y++) 
     { 
      if (GetRgbDelta(bmp.GetPixel(x, y)) <= highestRgbDelta) continue; 

      highestRgbDelta = GetRgbDelta(bmp.GetPixel(x, y)); 
      keyColor = bmp.GetPixel(x, y); 
     } 
    } 

    return keyColor; 
} 

/// <summary> 
/// Utility method that encapsulates the RGB Delta calculation: 
/// delta = abs(R-G) + abs(G-B) + abs(B-R) 
/// So, between the color RGB(50,100,50) and RGB(128,128,128) 
/// The first would be the higher delta with a value of 100 as compared 
/// to the secong color which, being grayscale, would have a delta of 0 
/// </summary> 
/// <param name="color">The color for which to calculate the delta</param> 
/// <returns>An integer in the range 0 to 510 indicating the difference 
/// in the RGB values that comprise the color</returns> 
private static int GetRgbDelta(Color color) 
{ 
    return 
     Math.Abs(color.R - color.G) + 
     Math.Abs(color.G - color.B) + 
     Math.Abs(color.B - color.R); 
} 
+0

Một số máy quét sẽ giới thiệu một chút màu sắc vào các hình ảnh đen trắng khác. Bạn nên cho phép một ngưỡng nhỏ cho màu sắc không hoàn toàn bằng nhau. – Andres

+0

Không phải hình ảnh có giá trị RGB là 128,128,128 tại TẤT CẢ pixel được coi là chỉ một hình chữ nhật màu xám (một màu)? – chrischu

+0

@crischu: Vâng, tôi nghĩ đó chỉ là một ví dụ cho thấy tất cả các giá trị sẽ như thế nào. – Beska

14

Nếu bạn không thể tìm thấy một thư viện cho điều này, bạn có thể thử lấy một số lượng lớn (hoặc tất cả) các pixel cho hình ảnh và xem nếu r, g, b và các giá trị của họ nằm trong một số ngưỡng (mà bạn có thể đặt theo kinh nghiệm, hoặc có một cài đặt) của nhau. Nếu có, hình ảnh là màu xám.

Tôi chắc chắn sẽ tạo ngưỡng cho thử nghiệm lớn hơn 0, mặc dù ... vì vậy tôi sẽ không kiểm tra r = g, ví dụ, nhưng (abs (rg) < e) trong đó e là ngưỡng của bạn . Bằng cách đó bạn có thể giữ màu giả của bạn tích cực xuống ... như tôi nghi ngờ bạn sẽ nhận được một số phong nha, trừ khi hình ảnh ban đầu của bạn và kỹ thuật quét cung cấp cho chính xác thang độ xám.

+0

+1, đặc biệt là đối với đề xuất ngưỡng. –

+0

Ai đó không công bằng đã bỏ phiếu bạn mà không bình luận. TSK tsk. –

+0

Yeah ... xảy ra. Buồn, nhưng * nhún vai *. – Beska

0

Vì JPEG có hỗ trợ siêu dữ liệu, trước tiên bạn nên kiểm tra xem phần mềm máy quét của bạn có đặt một số dữ liệu đặc biệt vào hình ảnh đã lưu hay không và liệu bạn có thể dựa vào thông tin đó hay không.

+0

Điều này không có ý nghĩa với tôi. Phần mềm quét, nếu nó ghi siêu dữ liệu vào tệp, sẽ ghi rằng hình ảnh là một hình ảnh màu nếu nó được quét dưới dạng màu (nghĩa là nó), ngay cả khi hình ảnh chỉ chứa nội dung màu xám. – Beska

+0

Đó là một ý tưởng và tôi đã chỉ ra để xác thực dữ liệu giả định này, beska. Anyways, ty cho bình luận của bạn. –

0

answer I posted in the python section có thể hữu ích. Hình ảnh bạn tìm thấy, ví dụ: trên trang web mà con người xem xét là thang độ xám thường không có giá trị R, G, B giống nhau. Bạn cần một số tính toán phương sai và một số loại quá trình lấy mẫu để bạn không phải kiểm tra một triệu pixel. Giải pháp mà Paul đưa ra là dựa trên sự khác biệt tối đa để một vật phẩm điểm ảnh màu đỏ duy nhất từ ​​một máy quét có thể biến một hình ảnh màu xám thành không màu xám. Giải pháp tôi đăng có độ chính xác 99,1% và thu hồi 92,5% trên 13.000 hình ảnh.

1

Một versión nhanh hơn. Thử nghiệm với một ngưỡng 8. Làm việc tốt cho

tôi sử dụng:

bool grayScale; 
Bitmap bmp = new Bitmap(strPath + "\\temp.png"); 
grayScale = TestGrayScale(bmp, 8); 
if (grayScale) 
    MessageBox.Show("Grayscale image"); 


/// <summary>Test a image is in grayscale</summary> 
/// <param name="bmp">The bmp to test</param> 
/// <param name="threshold">The threshold for maximun color difference</param> 
/// <returns>True if is grayscale. False if is color image</returns> 
public bool TestGrayScale(Bitmap bmp, int threshold) 
{ 
    Color pixelColor = Color.Empty; 
    int rgbDelta; 

    for (int x = 0; x < bmp.Width; x++) 
    { 
     for (int y = 0; y < bmp.Height; y++) 
     { 
      pixelColor = bmp.GetPixel(x, y); 
      rgbDelta = Math.Abs(pixelColor.R - pixelColor.G) + Math.Abs(pixelColor.G - pixelColor.B) + Math.Abs(pixelColor.B - pixelColor.R); 
      if (rgbDelta > threshold) return false; 
     } 
    } 
    return true; 
} 

Bạn có một nhanh hơn?

+0

Bạn đang cố gắng trả lời hoặc đặt câu hỏi. Xin hãy rõ ràng! – Samer

0

Tôi nghĩ rằng phương pháp này nên yêu cầu mã ít nhất, nó đã được thử nghiệm trên jpegs. bImage dưới đây là một mảng byte.

MemoryStream ms = new MemoryStream(bImage); 
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms); 
if (returnImage.Palette.Flags == 2) 
{ 
     System.Diagnostics.Debug.WriteLine("Image is greyscale"); 
} 
Các vấn đề liên quan