2012-10-02 40 views
6

Tôi đã xem ở khắp mọi nơi nhưng có vẻ như không phải là tiêu chuẩn (tôi có thể thấy) về cách một hình ảnh sẽ kiểm tra xem hình ảnh có trống không. Trong C#Kiểm tra xem hình ảnh có trống trong C#

Tôi có cách để làm điều này, nhưng rất muốn biết cách chính xác là kiểm tra xem hình ảnh có trống không, vì vậy mọi người cũng có thể biết trong tương lai.

Tôi sẽ không sao chép dán một loạt mã vào, nếu bạn muốn tôi, nó sẽ là niềm vui của tôi, nhưng tôi chỉ muốn giải thích cách tôi kiểm tra xem hình ảnh có trống không.

Bạn chụp ảnh .jpg, Nhận chiều rộng của ảnh. Ví dụ: 500 pixel Sau đó, bạn chia số đó theo 2 cho bạn 250

Sau đó, bạn kiểm tra màu của mỗi pixel ở vị trí (250 chiều rộng và chiều cao i) (nơi bạn lặp lại nghĩ rằng cao điểm của

Điều này chỉ làm là kiểm tra đường giữa của các điểm ảnh của một hình ảnh, theo chiều dọc.Theo mặc dù tất cả các điểm ảnh kiểm tra xem màu đó có là gì không Ngoại trừ màu trắng. để tìm kiếm TẤT CẢ 500 * chiều cao của pixel và vì bạn hầu như luôn luôn bắt gặp màu ở giữa trang.

Hoạt động của nó ... hơi chậm ... Phải có cách tốt hơn để làm điều này? Bạn có thể thay đổi nó để tìm kiếm 2/3/4 dòng theo chiều dọc để tăng cơ hội phát hiện một trang không trống, nhưng điều đó sẽ mất nhiều thời gian hơn.

(Cũng lưu ý, sử dụng kích thước của hình ảnh để kiểm tra xem nó có chứa một cái gì đó sẽ không làm việc trong trường hợp này, vì một trang có hai câu trên và kích thước một trang trống là quá gần nhau)

Sau khi giải pháp đã được thêm vào.

Tài nguyên để giúp triển khai và hiểu rõ giải pháp.

(Lưu ý rằng trên trang web đầu tiên, Pizelformat tuyên bố thực sự là Pixelformat) - Lỗi nhỏ tôi biết, chỉ cần nhắc đến, có thể gây nhầm lẫn cho một số người.

Sau khi tôi triển khai phương pháp để tăng tốc độ săn pixel, tốc độ không tăng nhiều. Vì vậy, tôi sẽ nghĩ rằng tôi đang làm điều gì đó sai trái.

Thời gian cũ = 15,63 cho 40 hình ảnh.

giờ New = 15.43 40 hình ảnh

tôi thấy với bài viết tuyệt vời DocMax quoted, rằng mã "khóa" trong một bộ pixel. (hoặc đó là cách tôi hiểu nó) Vì vậy, những gì tôi đã làm là khóa ở hàng giữa pixel của mỗi trang. Đó có phải là động thái đúng để làm?

private int testPixels(String sourceDir) 
    { 
     //iterate through images 
     string[] fileEntries = Directory.GetFiles(sourceDir).Where(x => x.Contains("JPG")).ToArray(); 

     var q = from string x in Directory.GetFiles(sourceDir) 
       where x.ToLower().EndsWith(".jpg") 
       select new FileInfo(x); 

     int holder = 1; 
     foreach (var z in q) 
     { 
      Bitmap mybm= Bitmap.FromFile(z.FullName) as Bitmap; 
      int blank = getPixelData2(mybm); 

      if (blank == 0) 
      { 
       holder = 0; 
       break; 
      } 
     } 
     return holder; 
    } 

Và sau đó các lớp

private unsafe int getPixelData2(Bitmap bm) 
     { 
      BitmapData bmd = bm.LockBits(new System.Drawing.Rectangle((bm.Width/2), 0, 1, bm.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat); 

      int blue; 
      int green; 
      int red; 

      int width = bmd.Width/2; 
      for (int y = 0; y < bmd.Height; y++) 
      { 
       byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride); 

       blue = row[width * 3]; 
       green = row[width * 2]; 
       red = row[width * 1]; 

       // Console.WriteLine("Blue= " + blue + " Green= " + green + " Red= " + red); 
       //Check to see if there is some form of color 
       if ((blue != 255) || (green != 255) || (red != 255)) 
       { 
        bm.Dispose(); 
        return 1; 
       } 
      } 
      bm.Dispose(); 
      return 0; 
     } 
+0

Bạn đã hẹn giờ phải mất bao lâu? Nếu vậy, thời gian và chiều cao của hình ảnh là bao nhiêu? – 3aw5TZetdf

+1

Bạn phải làm điều gì đó sai trong việc thực hiện của bạn, bởi vì thuật toán của bạn dường như âm thanh với tôi. Sẽ không mất thời gian để quét xuống một cột bitmap. –

+0

Tổng thời gian cho 32 hình ảnh = 00: 00: 12.9187389 Chiều cao = 6552 Chiều rộng = 4580 – Ruan

Trả lời

7

Nếu bạn có thể chịu đựng được khả năng mắc sai, phương pháp này có vẻ tốt đẹp; Tôi đã làm một cái gì đó rất giống nhau trong trường hợp của tôi, mặc dù tôi luôn luôn có một xác nhận hình ảnh để đối phó với các lỗi.

Đối với việc thực hiện, câu hỏi mở chính là cách bạn đang nhận được các điểm ảnh để kiểm tra. Nếu bạn đang sử dụng Bitmap.GetPixel, bạn nhất định có vấn đề về hiệu suất. (Tìm kiếm "Bitmap.GetPixel slow" trong Google để xem nhiều cuộc thảo luận.)

Hiệu suất tốt hơn sẽ đến từ việc nhận tất cả các pixel cùng một lúc và sau đó lặp lại chúng. Cá nhân tôi thích Bob Powell's LockBits discussion để rõ ràng và đầy đủ. Với cách tiếp cận đó, việc kiểm tra tất cả các pixel có thể hợp lý tùy thuộc vào nhu cầu hiệu suất của bạn.

+0

Bạn đang thực sự tại chỗ trên, tôi đang sử dụng Bitmap.GetPixel. Cảm ơn bạn, bệnh Kiểm tra giải pháp đó và đăng các phát hiện của tôi ở đây để có một giải pháp đầy đủ và "tôi dám nói" tiêu chuẩn về cách kiểm tra hình ảnh. – Ruan

+0

Vì vậy, tôi đã triển khai giải pháp. Điều duy nhất là, thời gian gần như giống hệt Thời gian cũ = 15,63 cho 40 Hình ảnh. Và thời gian mới là = 15,43 cho 40 hình ảnh. Ill giải thích là thông tin bổ sung về câu hỏi của tôi ở trên những gì tôi đã làm. – Ruan

+0

Nó tăng tốc nó với một phần nhỏ. Tôi nghĩ thật khó để thấy sự gia tăng với lượng dữ liệu tôi có. Cảm ơn bạn – Ruan

2

Nếu bạn đang sử dụng System.Drawing.Bitmap bạn có thể tăng tốc độ điều lên (đáng kể), bằng cách:

  1. Không sử dụng GetPixel để truy cập pixel, LockBits sử dụng và UnlockBits để sao chép các hình ảnh để bitmap bộ nhớ thông thường. Xem các ví dụ trên MSDN documentation để sử dụng.
  2. Không gọi thuộc tính Chiều rộng, Chiều cao hoặc Kích thước trong vòng lặp. Kích thước cuộc gọi một lần, lưu trữ các giá trị trong một biến địa phương và sử dụng các giá trị đó trong vòng lặp.

Ghi chú:

  1. Khi sử dụng System.Drawing.Bitmap hình ảnh của bạn có thể trong bộ nhớ điện thoại và truy cập vào nó có thể tốn nhiều thời gian.
  2. Tôi không nhớ liệu tải một hình ảnh vào một Bitmap đã chuyển đổi nó sang định dạng RGB như các định dạng khác là khó khăn hơn để làm việc với, nhưng nếu đó không phải là trường hợp bạn có thể tạo một RGB Bitmap có cùng kích thước như của bạn hình ảnh gốc, lấy đối tượng Graphic (Graphics.FromImage) và sử dụng DrawImage để vẽ hình ảnh gốc trong bitmap RGB.

Chỉnh sửa: Đánh bại cú đấm bằng DocMax.

Trong mọi trường hợp về tốc độ, bạn cũng có thể thử sử dụng các thư viện thay thế chẳng hạn như xuất sắc FreeImage bao gồm trình bao bọc C#.

0

Chia tỷ lệ hình ảnh thành 1x1 rồi chọn một pixel

Bitmap mới (previousImage, new Size (1, 1));

+0

Điều này thật tuyệt vời, tiếc là nó không hoạt động trên hầu hết các hình ảnh mà tôi đã thử với (một bộ 64x56 gạch có giá trị màu argb). Pixel đơn thường là 0,0,0,0 ngay cả khi nguồn chứa một số dữ liệu hình ảnh. – PeteB

+0

Tôi đã thử nghiệm thêm bằng cách sử dụng 2x2 và kiểm tra tất cả bốn pixel. Nó tốt hơn nhưng vẫn được báo cáo trống khi có một lượng nhỏ nội dung trong ô. – PeteB

Các vấn đề liên quan