Đơn vị cơ bản của một bức ảnh là điểm ảnh (pixel), mỗi điểm ảnh có thể được biểu diễn bằng n bytes dưới các hệ màu khác nhau. Việc chuyển đ...
Đơn vị cơ bản của một bức ảnh là điểm ảnh (pixel), mỗi điểm ảnh có thể được biểu diễn bằng n bytes dưới các hệ màu khác nhau. Việc chuyển đổi giữa các hệ màu thông thường được thực hiện thông qua các phép biến đổi ma trận. Trong bài viết này tôi sẽ giới thiệu phương thức chuyển đổi từ ảnh 24 bits RGB sang ảnh 8bits đa mức xám. Để thực hiện yêu cầu trên, thông thường ta sử dụng một trong những công thức sau đây, áp dụng cho từng điểm ảnh [x, y]:
Ix, y = 0.3086 * Redx, y + 0.6094 * Greenx, y + 0.0820 * Bluex, y
Ix, y = 0.299 * Redx, y + 0.587 * Greenx, y + 0.114 * Bluex, y
Chú ý rằng giá trị mỗi điểm ảnh Ix,y hay còn gọi là cường độ sáng (Luminance Intensity) trong ảnh đa mức xám tính được là tổng trọng số khác nhau của mỗi thành phần màu trong hệ màu RGB. Một trong những lý do của việc này là nếu chúng ta sử dụng cùng trọng số, ví dụ (R + G + B) / 3 thì màu đỏ, màu xanh nước biển hay màu xanh da trời sẽ có cùng mức xám sau khi chuyển đổi. Mặt khác theo khoa học đã chứng minh thì mắt người nhạy cảm hơn với thành phần màu xanh lá cây và màu đỏ so với xanh da trời.
Việc triển khai trong C/C++ của công thức trên khá đơn giản như sau với một ảnh có định dạng điểm ảnh liên tục (interleaved color) RGBRGB:
for ( i = 0; i < imgSize; i += 3 )
{
out[i] = (unsigned char)(0.299*in[i] + 0.587*in[i+1] + 0.114*in[i+2] + 0.5);
}
Vì việc thực hiện phép nhân trong miền số nguyên thì nhanh hơn rất nhiều trong miền số thực nên công thức trên được viết lại trong miền số nguyên như sau:
Ix, y = ( 2 * Redx, y + 5 * Greenx, y + 1 * Bluex, y ) / 8
Cộng với việc thay thế các phép chia và nhân bằng toán tử shift tốc độ của quá trình tính toán sẽ được đẩy lên một cách hiệu quả. Dưới đây là mã nguồn cho quá trình nâng cấp này:
int iTmp;
for ( i = 0; i < imgSize; i += 3 )
{
iTmp = in[i] << 1;
iTmp += in[i+1] << 2 + in[i+1];
iTmp += in[i+2];
out[i] = (unsigned char)(iTmp>> 3);
}
Và hãy cùng ngắm người đẹp lena trong kết quả
Để hiểu sâu hơn về tối ưu và phương pháp ánh xạ giữa các miền số học vui lòng xem thêm các bài viết trong mục kỹ thuật triển khai.
Lưu ý: trong thực hành, không phải lúc nào thứ tự của 3 bytes trong 1 điểm ảnh cũng là R - G - B, đôi khi thứ tự này có thể là B - G - R.
Lưu ý: trong thực hành, không phải lúc nào thứ tự của 3 bytes trong 1 điểm ảnh cũng là R - G - B, đôi khi thứ tự này có thể là B - G - R.
Binh Nguyen - Bioz
bạn có thể cho mình 1 bài hoàn chỉnh được không?
ReplyDeletebài này đã hoàn chỉnh, nội dung này là tất cả những gì tui muốn chuyển tải thông qua bài viết này :)
ReplyDeletebạn có thể cho mình một bài C/C++ hoàn chỉnh để tham khảo được không?Thanks bạn nhiều
ReplyDeleteNếu ý bạn cần là một chương trình hoàn chỉnh để tham khảo thì mong bạn thông cảm, chúng tôi không cung cấp mã nguồn nào khác ngoài VnSLib và VnPLib. Để có một chương trình hòan chỉnh bạn cần tích lũy kiến thức dần qua các bài viết trong mục kỉ thuật triển khai.
ReplyDeleteminh dang tim hieu nen anh. minh muon tim hieu cach chuyen tu anh xam sang he so C(i,j). ban giup minh voi
ReplyDeletebạn vui lòng dùng Tiếng Việt có dấu nếu không comment sẽ không được phép hiển thị!! tôi vẫn chưa hiểu lắm câu hỏi của bạn, hãy nói rỏ hơn, chi tiết hơn?
ReplyDeleteChào anh, em hiện đang làm đề tài như thế này : 1 webcam gắn vào 1 động cơ, khi có người đi vào vùng quan sát của webcam thì target người đó và khi người đó đi đâu thì webcame xoay theo để giám sát. anh có tài liệu hay hướng giải quyết nào giúp em target cơ thể người dù background thay đổi thì cho em xin để tham khảo
ReplyDeleteYM: [email protected]
anh cho em hỏi, làm thế nào để gọi được các hàm xử lý các điểm ảnh này ạ. Em sư dụng ngôn ngữ C#
ReplyDeletetất cả các xử lý chính đã được đề cập trong bài viết tuy nhiên tôi ko trình bày quá trình input ảnh và output như thế nào vì nó ko nằm trong phạm vi bài viết này. Quy trình sẽ bao gồm:
ReplyDelete1. đọc vào một bức ảnh
- load ảnh
- truy xuất vào từng điểm ảnh trong bộ nhớ
2. xử lý như đã trình bày ở trên
3. xuất ảnh ra màn hình
Quá trình 1 và 3 có thể được hỗ bằng thư viện như OPENCV cho C/C++, hay phiên bản OpencV for C# EMGU - CV. Bạn có thể sử dụng bộ ví dụ về OPENCV trong phần sản phẩm của IEEV để hiểu rõ quy trình, code cụ thể và hình dung ra cách xây dựng chương trình từ những bài viết như thế này.
anh ơi cho em hỏi ....tại sao lại nhân hệ số như thế ạ.....anh có thể giải thích thêm công thức ấy ạ...... thế còn nếu cho R = G = B thì sao ạ...ảnh là ảnh ji???????
ReplyDeletecó một vài vấn đề nên phần biệt trước:
ReplyDelete- hình đơn kênh: 1 Byte / 1 pixel -> là hình đa mức xám khi giá trị pixel trãi từ 0 - 255
- hình đơn kênh: 1 Byte / pixel là hình nhị phân khi giá trị pixel chỉ = 0 or 255. (trong xử lý có thể dùng 0 và 1).
- hình 3 kênh RGB: 3 byte / 1 pixel -> là hình màu nếu phối hợp 3 kênh riêng biệt.
- hình 3 kênh RGB: 3 byte / 1 pixel -> là đa mức xám nếu 3 kênh luôn giống nhau.
Bài viết này là để giải quyết bài toán, cho 1 hình 3 kênh màu, làm sao chuyển vể hình đơn kênh mà vẫn giữ nguyên nội dung. Công thức trên là phép biến đổi từ 3 thành phần sang chỉ còn 1 thành phần, như vậy nó phải trả lời cho câu hỏi mỗi thành phần input sẽ đóng góp bao nhiêu phần trăm trong giá trị 1 thành phần output. Tỉ lệ đóng góp này được tính toán dựa vào khảo sát sinh học, cảm nhận của thị giác đối với từng thành phần màu sắc ... Nó không thuộc phạm vi bài viết này, và cũng ko thể chứng minh do vậy ta tạm chấp nhận như vậy.
uh..vâng ạ...em hiểu ròi...anh cho em hỏi ..trong opencv khi load ảnh xám...nếu ko đặt tham số thứ 2 là CV_LOAD_IMAGE_UNCHANGE..thì em thấy số nchanel của nó vẫn là 3 và 3 thành phần RGB đều bằng nhau....ngược lại vậy nếu R = G = B thì ảnh đó cũng là ảnh xám???????...và 1 câu hỏi nhỏ nữa......^^.....để thao tác với ảnh thì ta thao tác với thuộc tính imageData.....vậy theo như thầy em nói thì trong ảnh không nhất thiết tổ chức theo thứ tự RGB mà là BGR...vậy để kiểm tra thứ tự schannel thì dựa vào thuộc tính channelSeq phải ko ạ......image->channelSeq == "BGR" ????.....^^..thank anh nhiu
ReplyDelete- anh nghĩ rằng em ko nên sử dụng ... và ??? quá nhiều, nó không thích hợp cho vị trí của một người đi hỏi bài.
ReplyDelete- Bài viết này ko hề đề cập tới opencv nên có vẻ như em đang nói 2 vấn đề ko liên quan. Vì vậy chuyện thứ tự RGB hay GBR hay gì gì thì đó chỉ là vấn đề implement của thư viện, cái đó thì em nên tham khảo sách về opencv là tốt hơn, em có thể download nó trong mục sách hay của blog này.
- em có vẻ vẫn chưa đọc kỉ câu trả lời, và vẫn chưa hiểu câu trả lời một cách đầy đủ và đúng đắn. Trên thực tế khi nói về hình xám người ta ám chỉ tới hình 1 byte / 1 pixel. Tuy nhiên người ta cũng có thể nói một hình là xám nếu nó chỉ thể hiện dạng xám, điều đó có nghĩa là dù n kênh màu mà mỗi kênh ko độc lập và có giá trị luôn luôn như nhau em có thể coi là xám. Tuy nhiên, khi cho một ảnh màu em sử dụng gán R=G=B thì đó tuy cũng là chuyển đổi hình xám nhưng không giữ nguyên được nội dung, vì vậy nó hoàn toàn khác với những gì được đề cập ở trên.
Vui lòng thay đổi cách viết câu hỏi và nghiêm túc hơn nếu ko câu hỏi của em se ko được hiển thị, đồng thời cũng ko nên đưa người thứ 3 vô danh vào để thảo luận ví dụ như "thầy em" trên blog này!?
em hiểu rồi, cảm ơn anh, em không nghĩ câu văn của em lại làm ông anh bực mình , em sẽ rút kinh nghiệm theo lời anh vậy, sori
ReplyDelete:) em hiểu thì tốt, anh ko bực mình, chỉ muốn em hiểu là trên mạng ngoài bạn em ra thì phần còn lại là đàn anh, thầy và người lớn hơn em rất nhiều. Với những đối tượng này nên tỏ ra cầu thị, lịch sự, đừng có teen quá, tránh người ta ghét thì ko có lợi.
ReplyDeleteAnh ơi em mới học xử lý ảnh,em vẫn chưa hiểu ảnh 4 màu là gì và thủ tục hiện ảnh bằng kỹ thuật phân ngưỡng 4 màu nữa.Anh giúp em giải đáp với ạ!
ReplyDeleteem thông cảm anh ko thể trả lời các câu hỏi như thế này vì anh cũng ko hiểu em hỏi gì, do anh chủ yếu đọc tài liệu tiếng anh nên anh rất khó để hiểu vấn đề, anh nghĩ là em đang muốn đề cập tới một hệ màu nào đó có 4 thành phần ...
ReplyDeleteAnh cho em hỏi phương pháp xác định góc nghiêng của văn bản
ReplyDeleteCho mình hỏi là i tại sao <=3 vậy ?
ReplyDelete3 là số kênh màu, trong tình huống này là mỗi điểm ảnh có 3 byte. do vậy để nhảy tuần tự qua từng điểm ảnh i phải + 3.
ReplyDeleteBro ơi , bro có tài liệu xử lý ảnh trên các kit xử lý ảnh và video của Texas Instrument như TMS320DM6437 share cho mình được không ạ, nếu được xin send qua email [email protected] cho mình. Thanks bro nhiều lắm ạ.
ReplyDeletecái này là căn bản trước tiên nên coi:
ReplyDeletehttp://processors.wiki.ti.com/index.php/Accessing_Pixels_in_a_Frame_on_the_DM643x
có ví dụ này rồi em muốn xử lý ảnh chỉ việc chen mã xử lý ảnh của mình vào giữa input và output là xong.
Để hiểu thêm thì em nên tìm hiểu kiến thức về hệ màu yuv, rgb, đọc datasheet của chíp và board. Nghiên cứu từng ví dụ trong bộ evmdm6437_v2.
Bài viết khá hay thanks chủ blog
ReplyDeletebạn ơi cho mình hỏi cách tính chu vi ảnh nhị phân vaf anhr đa mức xám
ReplyDeleteCho e hỏi để convert 1 anh 8bit (bitmap) sang ảnh 24bit thì có những hướng nào a?
ReplyDelete