Giáo trình Xử lý ảnh - Chương 11: Xử lý ảnh màu

Tài liệu Giáo trình Xử lý ảnh - Chương 11: Xử lý ảnh màu: Chương 11 Xử lý ảnh màu 11.1 Chỉ dẫn Cần nhấn mạnh rằng trong các chương trước chúng ta xử lý trực tiếp ảnh đen trắng (ảnh có mức xám). Bây giờ chúng ta sẽ quan tâm đến xử lý các ảnh màu. Bây giờ, chúng ta sẽ bắt đầu xem xét các cơ sở của màu sắc, sau đó chúng ta đề cập đến các kỹ thuật áp dụng trong xử lý ảnh màu. Chúng tôi sẽ đề cập đến bộ lọc 2-D cho ảnh màu, và trình bày trình tự xử lý ảnh màu dựa trên trình tự xử lý ảnh đen trắng. Chúng tôi cũng sẽ phát triển một kỹ thuật lọc ảnh màu có lựa chọn. Điều này cho phép chúng ta điều chỉnh được một sắc màu riêng biệt (tint), ví dụ như tăng sắc màu này lên mà không làm thay đổi các sắc màu còn lại trên ảnh. 11.2 Cơ sở của màu sắc ánh sáng là một dạng của năng lượng sóng điện từ có bước sóng vào khoảng từ 400 mm (millimicron) cho ánh sáng tím và vào khoảng 700 mm cho ánh sáng đỏ (hình 11.1). Tất cả các bước sóng này được cảm nhận bởi mắt người như là một sắc màu. Tất cả các sắc màu này nằm trong ánh sáng trắng của mặt trời, với ...

doc32 trang | Chia sẻ: hunglv | Lượt xem: 1232 | Lượt tải: 1download
Bạn đang xem trước 20 trang mẫu tài liệu Giáo trình Xử lý ảnh - Chương 11: Xử lý ảnh màu, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Chương 11 Xử lý ảnh màu 11.1 Chỉ dẫn Cần nhấn mạnh rằng trong các chương trước chúng ta xử lý trực tiếp ảnh đen trắng (ảnh có mức xám). Bây giờ chúng ta sẽ quan tâm đến xử lý các ảnh màu. Bây giờ, chúng ta sẽ bắt đầu xem xét các cơ sở của màu sắc, sau đó chúng ta đề cập đến các kỹ thuật áp dụng trong xử lý ảnh màu. Chúng tôi sẽ đề cập đến bộ lọc 2-D cho ảnh màu, và trình bày trình tự xử lý ảnh màu dựa trên trình tự xử lý ảnh đen trắng. Chúng tôi cũng sẽ phát triển một kỹ thuật lọc ảnh màu có lựa chọn. Điều này cho phép chúng ta điều chỉnh được một sắc màu riêng biệt (tint), ví dụ như tăng sắc màu này lên mà không làm thay đổi các sắc màu còn lại trên ảnh. 11.2 Cơ sở của màu sắc ánh sáng là một dạng của năng lượng sóng điện từ có bước sóng vào khoảng từ 400 mm (millimicron) cho ánh sáng tím và vào khoảng 700 mm cho ánh sáng đỏ (hình 11.1). Tất cả các bước sóng này được cảm nhận bởi mắt người như là một sắc màu. Tất cả các sắc màu này nằm trong ánh sáng trắng của mặt trời, với năng lượng nằm trong khoảng từ hồng ngoại đến cực tím. Màu sắc của một vật thể là một hàm của các bước sóng không bị hấp thụ phản chiếu từ vật thể. Đó là lý do tại sao mà một vật thể có các màu sắc khác nhau phụ thuộc vào ánh sáng mà nó được quan sát. Một vật thể khi quan sát dưới ánh sáng mặt trời sẽ có màu khác khi nó được quan sát dưới ánh sáng đèn điện. Phần lớn kiến thức cơ sở cho hiểu biết của chúng ta về màu sắc dựa trên tìm tòi của Isaac Newton và học thuyết quang học của ông. Newton kết luận rằng cảm giác của chúng ta về màu sắc là do tác động sự phản xạ có chọn lọc về bước sóng các tia sáng tới. Ông ta cho rằng màu sắc vật thể có nguyên nhân bắt nguồn từ phản xạ bước sóng chọn lọc của truyền đạt các tia sáng xuất phát từ vật thể. Newton đã trình bày một hỗn hợp của hai màu có phổ liên tiếp cho ta một màu phổ trung gian, nhưng hỗn hợp của hai màu có phổ xa nhau đỏ và lam cho ta màu đỏ tía, một màu không phổ. Ông ta cũng giới thiệu một loạt màu mà khi tổng hợp với nhau cho màu trắng. Ông gọi các màu này là các màu chính, bao gồm bảy màu: đỏ, da cam, vàng, lục, lam, chàm, tím, và được dùng để tính các màu có bước sóng khác nhau. Thực tế, cuối cùng người ta đã khám phá ra rằng bất kỳ màu nào cũng được tạo ra bởi một tỷ lệ thích hợp của ba màu có phổ riêng biệt, mà bất kỳ màu nào trong số ba màu này cũng không thể tạo ra bằng tổng hợp của hai màu còn lại. Ba màu này gọi là ba màu riêng (màu chính), được kết hợp với nhau khi tổng hợp ánh sáng màu, được tách ra khi phân tích thành các màu thành phần, như giới thiệu trong hình 11.2. Trong hình 11.2a, hệ thống tổng hợp ánh sáng được giới thiệu với các màu riêng hay dùng nhất: đỏ, lục, lam. Cộng màu đỏ và màu lục kết quả cho ta màu vàng. Cộng ba màu đỏ, lục, lam theo tỷ lệ thích hợp cho ta màu trắng. Hai màu được bổ sung, khi trộn với tỷ lệ thích hợp, cho màu trắng. Màu đỏ tươi, ví dụ, khi trộn với tỷ lệ bù thêm vào của màu lục, cho ta màu trắng, như giới thiệu trong tam giác màu ở hình 11.2a. Vì vậy, màu đỏ tươi là màu bù của màu lục. Các phân tích riêng cho các màu nhuộm thành phần là phần bù của các màu tổng hợp của ánh sáng (hình 11.2b). Các màu riêng phân tích khi trộn tỷ lệ cho kết quả là màu đen. Hầu hết các màu đều dựa trên hai tam giác giới thiệu trong hình 11.2. 1 1 1 1 1 1 Ao mm m mm m km Tia nhìn thấy UV 400 500 600 700 Tím Lam Chàm Lục Vàng Da cam Đỏ Tia vũ trụ Tia g Tia x IR Sóng radio SHF UHF VHF SW MW LW Đỏ Đen Đỏ tươi Lam Lục lam Vàng Lục (b) Hình 11.1 Dải sóng của các ánh sáng nhìn thấy được. Lục lam Trắng Lục Vàng Đỏ Lam Đỏ tươi (a) Hình 11.2 Tổng hợp màu theo phương pháp cộng và trừ. Để xác định một ánh sáng màu thì các yếu tố sau đây cần đề cập đến : Độ sáng hay chói. Nó là tổng hợp của ánh sáng nhận được bởi mắt không kể tới màu sắc. Nó nằm trong khoảng từ lờ mờ tối đến rất sáng hoặc chói mắt . Sắc màu. Chính là màu có phổ trội hơn trong ánh sáng. Bão hoà màu. Nó tạo ra độ tinh khiết phổ của màu trong ánh sáng. Cho một hỗn hợp của màu và đen trắng, độ bão hoà màu được tăng thêm bởi tăng của tổng các sắc màu. Những tính chất này có thể mô tả bằng sơ đồ như trong hình 11.3. Có tám tính chất cơ bản quyết định hỗn hợp của ba màu: 1. Một điểm màu tổng hợp thì độc lập đối với độ sáng trên một phạm vi rộng. 2. Độ sáng của một hỗn hợp các màu là tổng của các độ sáng riêng lẻ. 3. Bất kỳ một màu nào cũng được tạo ra bởi một hỗn hợp không nhiều hơn ba màu thành phần. 4. Các màu thành phần không thể nhận ra được bằng mắt. 5. Một điểm màu có thể biểu diễn dưới dạng biểu thức C = R(R) + G(G) + B(B) Có nghĩa là R là đơn vị của (R), G là đơn vị của (G), B là đơn vị của (B), khi tính tổng tạo ra một điểm với màu C. 6. Các màu được kết hợp theo luật cộng. Giả sử C1 kết hợp với C2 kết hợp C3 kết hợp C4 , thì C1 + C3 kết hợp C2 + C4 . Quy tắc này được gọi là luật Grassman. 7. Các màu kết hợp tuân theo luật trừ. 8. Các màu kết hợp tuân theo luật bắc cầu. Nếu C1 kết hợp C2 và C2 kết hợp C3 thì C1 kết hợp với C3. Lục Đỏ Vàng Sáng nhất Bão hoà Giới hạn của cảm giác Màu sắc Tối nhất Lam Tía Hình 11.3 Thuộc tính của màu. 11.2.1 Nhận biết màu sắc Mắt người có hai bộ phận cảm nhận ảnh: tế bào nón và tế bào gậy. Chúng nằm trên màng trong cùng của mắt, gọi là võng mạc, và chúng cảm nhận vật thể qua ảnh của vật thể đó trên võng mạc. Trong toàn bộ mắt thì các tế bào nón có vào khoảng sáu đến bảy triệu. Chúng nằm tập trung ở vị trí trung tâm của võng mạc gọi là hố võng mạc, và có độ nhạy cảm cao đối với màu sắc. Con người sở dĩ có thể phân biệt được các chi tiết là vì các tế bào nón này được nối với các dây thần kinh ở phía cuối. ảnh thu được từ các tế bào nón này gọi là các hình ảnh độ sáng. Số tế bào gậy thì rất lớn, vào khoảng từ 75 cho đến 100 triệu và chúng được phân bố đều khắp bề mặt võng mạc. Sự phân bố rộng cùng với thực tế là tế bào gậy đều được nối một dây thần kinh riêng tạo ra kết quả là sự tổng hợp các chi tiết bởi bộ phận cảm nhận này. Tế bào gậy cung cấp cho ta một hình ảnh toàn bộ của vật thể không bao gồm các chi tiết về màu sắc và độ sáng. Trong ánh sáng mờ thì chỉ có tế bào gậy bị kích thích và vật thể hiện lên như một ảnh không có màu sắc. Đặc tính này gọi là khả năng thích ứng nhìn tối. Lý do mà con người có thể phân biệt được màu sắc thì hiện nay vẫn chưa được làm rõ ràng. Một giả thiết là mắt con người có ba loại tế bào nón, mỗi loại cho cảm ứng với một loại màu sắc riêng là: đỏ, lục, lam. Cảm nhận của các tế bào nón này được trải ra trên một dải tần số rộng. Sau nhiều lần thử nghiệm, các màu riêng đã được chuẩn hoá bởi ủy ban CIE (Commission International d'Eclairage). Các màu riêng theo tiêu chuẩn của CIE bao gồm: màu đỏ (700 nm), màu lục (546,1 nm), màu lam (435,8 nm). Mắt của con người cho một cảm nhận tốt nhất đối với các màu riêng này so với các màu còn lại. Cảm nhận màu sắc phụ thuộc rất lớn vào độ sáng. Màu sắc được cảm nhận tốt hơn khi độ sáng tăng lên. Một ảnh tốt thực sự thì sẽ cho một cảm nhận cao hơn về độ sáng so với các ảnh còn lại. Trong hình 11.4 đưa ra đường cong cảm nhận độ sáng của mắt người đối với các ánh sáng có bước sóng khác nhau với cùng một mức năng lượng. Mắt người cảm nhận tốt nhất với màu lục (bước sóng vào khoảng 555 nm). Khả năng phân biệt sự chuyển dần màu sang các màu tương tự bị hạn chế. Chính vì hạn chế này của mắt người mà một số sản phẩm về màu được sản xuất trong thực tế vẫn thoả mãn yêu cầu, thậm chí người ta có thể cắt bớt một số trong phổ màu thực. 11.2.2 Biểu thức màu Các màu riêng RGB: đỏ (Red), lục (Green), lam (Blue) là các màu riêng vật lý được dùng trong các thí nghiệm vật lý thực sự. Các màu riêng này không phải là duy nhất và ta có thể dùng các màu riêng khác để thay thế. Vào năm 1938, CIE đã đưa ra một tập các màu riêng không vật lý, ký hiệu là X, Y, Z. Cải tiến chính trong tập màu này là độ sáng được đưa ra trực tiếp như là một màu riêng (Y). Y sẽ cho ta mức xám từ ảnh màu. Các màu riêng này được rút ra từ các màu riêng vật lý theo biến đổi tuyến tính cho bởi : X = 2.7690R + 1.7518G + 1.1300B Y = 1.0000R + 4.5907G + 0.0601B (11.1) Z = 0.0000R + 0.0565G + 5.5943B Hình 11.4 Sự cảm nhận cường độ sáng của mắt người. Các biểu thức này là đúng cho bất kỳ màu nào. Dựa trên các X, Y, Z sơ đồ màu CIE đã được phát triển. Sơ đồ này là một không gian biểu diễn cho tất cả các màu có phổ và tổng hợp của chúng (Hình 11.5). Toạ độ màu rút ra từ : D = X + Y + Z (11.2) x + y + z = 1 Hình 11.5 Biểu đồ màu CIE. Trong sơ đồ CIE một loạt các màu có phổ được cho dọc theo đường cong, các góc biểu diễn cho ba màu riêng: đỏ, lục, và lam. Gần trung tâm của miền nằm trong tam giác các màu trở nên ít bão hoà hơn, biểu diễn cho hỗn hợp màu. Màu trắng nằm tại điểm trung tâm w với toạ độ x = y = 0.3333. Sơ đồ màu trên chứa các màu với cùng một độ sáng. Nếu độ sáng của màu được cho bởi giá trị của z tại góc bên phải của mặt phẳng x-y, tất cả các màu với độ sáng của nó sẽ có dạng như hình 11.6. Nếu độ sáng tăng lên, sơ đồ màu sẽ trở nên rộng hơn và sẽ có nhiều chi tiết màu trông thấy. Tại các mức độ sáng thấp, các màu trở nên kkó phân biệt và sơ đồ sẽ thu hẹp lại một điểm, biểu diễn cho màu đen. 11.3 ảnh màu Nếu bạn kiểm tra màn hình của một tivi khi nó được bật lên, bạn sẽ chú ý thấy tại tất cả các điểm ảnh màu được tạo nên bằng ba vòng tròn nhỏ hoặc tam giác có màu đỏ, lục, lam. Sự thay đổi độ sáng của ba phần tử màu này tạo nên màu sắc của điểm ảnh. Trong ảnh số thì các điểm ảnh được biểu diễn bằng một số từ có cùng một số bit cho các màu đỏ, lục, lam. Ví dụ như ảnh màu được biểu diễn bằng 16 bit thì đều có 5 bit để biểu diễn cho mỗi màu, bit cuối cùng dùng cho một vài chức năng đặc biệt như ngăn xếp. Trong một khung số thì bit cuối cùng thông thường để chỉ ra điểm ảnh này được lấy từ bộ đệm khung (bộ nhớ ngăn xếp) hay là từ tín hiệu video bên ngoài (ngăn xếp trực tiếp). Trong hệ thống 16 bít 32,768 màu có thể được biểu diễn với ba màu riêng có khả năng thể hiện 32 trạng thái. Cấu tạo của một điểm ảnh cho trong bảng 11.1. R B Đen Độ chói W ã ã Bóng xám G Hình 11.6 Hình chóp màu. 11.4 Tính sơ đồ màu cho các hệ thống màu 15 bit và 8 bit Để làm mở rộng hiểu biết của chúng ta về hỗn hợp màu, chúng ta sẽ làm một chương trình tính và thể hiện sơ đồ màu cho hệ thống 15 bit (5 bít cho một màu) và hệ thống màu 8 bit (256 màu). Hệ thống 15 bit màu mà chúng ta sử dụng là Professional Image Board (PIB) của Atronics International, Inc. (ATI). Vỉ mạch này được thiết kế để thể hiện ảnh có kích thước 512 ´ 256 hoặc là 512 ´ 512 điểm, với tất cả các điểm biểu diễn bằng 16 bit. 16 bit này được chia như trong bảng 11.1. Vỉ mạch VGA có khả năng thể hiện 256 màu với tất cả các màu thể hiện bằng 6 bit. Tổng số màu mà vỉ mạch VGA có thể tính ra là 218 = 262,144. Dù thế nào đi chăng nữa thì chỉ có 256 màu được sử dụng. Một vỉ mạch này tương đương như là thiết bị video màu 8 bit. bảng 11.1 Biểu diễn của điểm ảnh màu 16 bit Bít 0 đến bít 4 Lam Bít 5 đến bít 9 Lục Bít 10 đến bít 14 Đỏ Bít 15 Overlay Vỉ mạch ATI PIB được chia ra làm hai mã nguồn: một bằng Microsoft Assembly cho các chương trình vào ra cơ bản, một bằng Microsoft C cho các chương trình chính (như lấy ra khung ảnh hoặc là sửa lại màu). Mặc dù bạn có thể đưa ra phần lớn các chương trình trong chương này mà không cần vỉ mạch lưu giữ khung màu, nhưng để làm cho đầy đủ công việc tôi khuyên bạn nên sử dụng một vỉ mạch có chế độ ít nhất là 512 ´ 256. Nó không quá đắt, thậm chí nó rẻ hơn một số vỉ mạch đen trắng. Tôi sẽ cung cấp cho bạn các chương trình con dùng cho loại vỉ mạch này, nếu bạn có một loại vỉ mạch khác thì không phải là khó khăn lắm để viết lại các sửa đổi cho phù hợp. Chương trình mà tôi đưa ra trong chương này được viết bằng Turbo C. Nó sẽ đòi hỏi phải có một thay đổi nhỏ trên mã nguồn cung cấp cho vỉ mạch ATI, PIBTOOL.C và IMGIO.ASM. Để dịch và liên kết thành một chương trình (tên là CHROM.C) bạn có thể làm điều này thông qua Project trên menu lựa chọn của môi trường phát triển kết hợp hoặc là đánh dòng lệnh DOS : tcc chrom.c pibtool.c imgio.asm Trước khi xử lý, bạn sẽ cần viết một file "custom.h" chứa một loạt các chương trình nguồn sử dụng trong hai chương trình IMGIO.ASM và PIBTOOL.C. Danh sách của "custom.h" được cung cấp sau chương trình 11.1. Đặt "custom.h" nằm ở thư mục con Turbo C. Chương trình cho vỉ mạch PIB được viết cho kiểu 512 ´ 256. Các bạn cũng có thể dùng nó với kiểu 512 ´ 512 mà không cần có một sự thay đổi nào. Nếu bạn muốn sử dụng đầy đủ khả năng của kiểu 512 ´ 512 thì bạn cần một số thay đổi nhỏ. Nếu khả năng tài chính không cho phép bạn có một vỉ mạch như vậy, thì bạn có thể dùng vỉ mạch VGA thay thế. Bây giờ chúng ta sẽ quay lại với sơ đồ màu CIE. Mã nguồn dùng trong chương trình 11.1 cho hiện lên sơ đồ màu trên một monitor màu dùng vỉ mạch PIB. Chương trình 11.1 "CHROM.C".Displaying the chromaticity diagram. #include /* Program for displaying the chromaticity diagram using the ATI PIB board, 512x256 version. */ void main() { unsigned i,R,G,B; int xp,yp; float x,y,X,Y,Z,D; InitPIB(); /* Initials the PIB to the internal display mode.*/ SetInDispMode(); /* Sets PIB to the internal Sync display mode and also enables the direct memory access. */ SetScreen(0); /* Display page 0 512x256. */ FillPibRect(0,0,0,511,255,0); /* Clear screen. FillPibRect(color,xl,yl,x2,y2,mode); fills the rectangle area specified by the two corners (xl,yl) and (x2,y2) with color. mode=0 for set the pixel to the value specified. mode=1 for 'exclusive or' the pixel with the value specified. mode=2 for 'and' the pixel with the value specified.*/ for(i=1;i<32768;i++) { B=(0x001F & i); G=(0x03E0 & i)>>5; R=(0x7C00 & i)>10; X=2.7690*R+1.7518*G+1.1300*B; Y=R+4.5907*G+0.0601*B; Z=0.0565*G+5.5943*B; D=X+Y+Z ; x=X/D; y=Y/D; xp=(int)(400.0*x+60.0+0.5); yp=(int)(200.0-y*200.0+0.5); PutPixel(&i,xp,yp,0); /* PutpixeI(*vaIue,x,y,mode) */ } } File include "custom.h" chứa các một loạt chương trình con cung cấp bởi ATI. Nếu chưa được cung cấp bởi ATI bạn có thể tự viết lấy các chương trình này. Liệt kê cho "custom.h" cung cấp ở dưới đây. "custom.h" void SetScreen(int); int CaptureFrame(void); void SetInDispMode(void); void SetExtDispMode(void); void SetLiveMode(void); void SetHue(int); void SetContrast(int); void SetSaturation(int); void Bright(int); void SetInterlace(int); void SetMask(unsigned); void SetCamera(int); void SetPIBorEGA(int); void SetBlank(int); void FillPibRect(unsigned,int,int,int,int,int); void WaitEven(void); void WaitOdd(void); int InitPIB(void); int TestRow(int); int WaitVsync(void); void FillPibRow(unsigned,int,int,int,int); void FGetPibRow(char far *,int,int,int); void FPutPibRow(char far *,int,int,int); void GetPibRow(char far *,int,int,`int); void PutPibRow(char far *,int,int,int); unsigned GetPixel(unsigned *,int,int); void PutPixel(unsigned *,int,int,int); void SaveData(unsigned,unsigned,int); void SetBright(int); Biểu đồ màu cho các màu tính ra bằng vỉ mạch PIB được giới thiệu ở cuối cuốn sách này. Nếu bạn có phần kiểm tra vật lý của "độ sáng" (ví dụ như College Physic) bạn sẽ có thể so sánh biểu đồ màu của kiểm tra vật lý với kết quả rút ra từ chương trình 11.1. Nếu hệ thống có khả năng hiện nhiều màu hơn bạn sẽ có một sơ đồ dày đặc hơn. Bây giờ ta sẽ so sánh vỉ mạch PIB với vỉ mạch VGA. Để làm như việc này bạn sẽ phải tính ra một bảng màu có cùng một số mức của đỏ, lục, lam. Nếu các màu chính có 26 = 64 mức trên VGA, bạn có thể chọn các mức 0, 12, 24, 36, 48, và 60 cho tất cả các màu đỏ, lục, lam để xác lập ra bảng cân bằng màu. Vì vậy mà ta có tổng cộng 6 ´ 6 ´ 6 = 216 màu. Bây giờ đưa 216 màu này vào vỉ mạch VGA. Khi tính 32,680 màu cho chuyển đổi 15 bit/ điểm, bạn nhóm 6 màu lại với nhau, chẳng hạn, (R/6) ´ 6 ,...v.v.., ở đây R,G,B là giá trị nguyên. Nếu được biểu diễn ảnh 5 bit màu, bạn cần nhân kết quả với 2 để chuyển sang dạng 6 bit/màu như trường hợp tương thích với VGA. Biết R,G,B chúng ta có thể tính địa chỉ của bảng màu dùng Address = (B/6+G+R´6) / 2 Mã chương trình cho hiện sơ đồ biểu đồ trên VGA như ví dụ trên cho ở chương trình 11.2 Chương trình 11.2 "CHROMVGA.C". Displaying the chromaticity diagram on a VGA card. /* Program for displaying chromaticity diagram using a VGA. The program emulates a video card capable of 15 bits/pixel.*/ #include #include #include #include #include void main() { int xp,yp,l,R,G,B; unsigned i; float x,y,X,Y,Z,D; unsigned char a[648],b[648],display_mode,active_page; int color; char far *farptr; union REGS reg; struct SREGS sreg; clrscr(); /* Generate color palette. We assume 6 bits per color for VGA, and therefore the range will extend from 0 to 63per color. */ l=0 ; for(R=0;R<64;R+=12) for(G=0;G<64;G+=12) for(B=0;B<64;B+=12) { a[1]=R; a[++l]=G; a [++l]=B; l++; } /* Get current mode. */ reg.h.ah=0x0F; int86(0x10,®,®); display_mode=reg.h.al; active_page=reg.h.bh; /* Setting display mode to 32Ox2OO. */ reg.h.ah=0; reg.h.al=0x13; int86(0x10,®,®); /* Read color palette.*/ reg.h.ah=0x10; reg.h.al=0x17; reg.x.bx=0; reg.x.cx=216; sreg.es=FP_SEG(b); reg.x.dx=FP_OFF(b); int86x(0x10,®,®,&sreg); /* Setting new color palette. */ reg.h.ah=0x10; reg.h.al=0x12; reg.x.bx=0; reg.x.cx=216; sreg.es=FP_SEG(a); reg.x.dx=FP_OFF(a); int86x(0x10,®,®,&sreg); for(i=1;i<32768;i++) { R=(0x001F&i); B=(0x03E0 & i) >> 5; G=(0x7C00 & i) >> 10; X=2.769*R+1.7518*G+1.1300*B; Y=R+4.5907*G+0.0601*B; Z=0.0565*G+5.5943*B; D=X+Y+Z; x=X/D; y=Y/D; xp=(int)(300.0*x+0.5); yp=(int)(190.0-y*190+0.5); /* Group every 6 colors in red, green and blue,i.e. (R/6)*6, and then multiply by 2 to spread the range from 0 to 63 (6-bits.) */ R=(R/6)*12; G=(G/6)*12; B=(B/6)*12; color=(B/6+G+R*6)/2; /* position in palette. */ reg.h.ah=0x0C; reg.h.al=(char)color; reg.h.bh=0; reg.x.cx=xp; reg.x.dx=yp; int86(0x10,®,®); } getch(); /* Restore previous color palette. */ reg.h.ah=0x10; reg.h.al=0x12; reg.x.bx=0; reg.x.cx=216; sreg.es=FP_SEG(b); reg.x.dx=FP_OFF(b); int86x(0x10,®,®,&sreg); /* Restore previous mode and page. */ reg.h.ah=0x00; reg.h.al=display_mode; int86(0x10,®,®); reg.h.ah=0x05; reg.h.al=active_page; int86(0x10,®,®); } 11.5 Hiển thị ảnh màu trên hệ thống màu 15 bit và 8 bit Phần sắp tới chúng ta sẽ xây dựng chương trình cho hiển thị ảnh và sửa lại màu, độ sáng ..., trên vỉ mạch PIB. Chương trình cũng bao gồm nén và chứa ảnh trên một file. Sau đó là một chương trình cho hiển thị ảnh màu bằng vỉ mạch VGA. Chương trình 11.3 "DISPPIB.C". To display, freeze, and save an image on the PlB board. /* Program for displaying images in live mode through the PIB board. Through the program you can adjust colors, brightness,etc..You are also given the choices to freeze and save the image to a file. */ #include #include #include #include #include #include #define U_ARROW 0x48 #define D_ARROW 0x50 void main() { int ind,k1,k2,k3,k4,ind2,i; char a; char buff[1024],file_name[30]; FILE *fptro; clrscr(); InitPIB(); SetScreen(0); SetInDispMode(); SetCamera(0); SetInterlace(0); SetLiveMode(); k1=140; k2=126; k3=162; k4=44; SetHue(k1); SetContrast(k2); SetSaturation(k3); SetBright(k4); textattr(WHITE+(BLUE<<4)); cputs("Do you wish to adjust colors? y or n-->"); ind=1; while (ind) { a=getche(); switch(a) { case 'Y': case 'y': gotoxy(1,2); cputs("Adjusting colors:"); cputs(" To adjust colors press H or C or S or B,"); gotoxy(1,3); cputs("for Hue, Contrast, Saturation, and Brightness,"); cputs(" respectively."); gotoxy(1,4); cputs("You can also use the up and down arrow keys."); gotoxy(1,5); cputs(" Then press + to increase or - to decrease"); cputs(" value."); gotoxy(1,6); cputs( " To exit adjustment press ESC\n"); gotoxy(30,8); textattr(WHITE+(RED<<4)); cprintf("Hue %4d",k1); gotoxy(30,9); cprintf("Contrast %4d",k2); gotoxy(30,10); cprintf ( "Sat urati on %4d",k3); gotoxy(30,11); cprintf ( "Brightness %4d",k4); a=getch(); ind2=1; i=-1; while(ind2) { if((a==D_ARROW)||(a==U_ARROW)) { switch(a) { case D_ARROW: i++; if(i>3) i=0; break; case U_ARROW: i--; if(i<0) i=3; } switch(i) { case 0: a='H'; break; case 1: a='C'; break; case 2: a='S'; break; case 3: a='B'; } } textattr(WHITE+(GREEN<<4)); gotoxy(1,10); cprintf("Key pressed %c\n",a); switch(a) { case 'h': case 'H': gotoxy(30,8); cprintf("Hue %4d",k1); while(((a=(char)getch())=='+')||(a=='-')) { switch(a) { case '+': ++k1 ; if(k1>255) k1=0; break; case '-': --k1; if(k1<0) k1=255; } SetHue(k1); gotoxy(30,14); cprintf("Key pressed %c",a); gotoxy(30,8); cprintf("Hue %4d",k1); } textattr(WHITE+(RED<<4)); gotoxy(30,8); cprintf("Hue %4d",k1); break; case 'c': case 'C': gotoxy(30,9); cprintf("Contrast %4d",k2); while(((a=(char)getch())-='+')||(a-='-')) { switch(a) { case '+': ++k2 ; if(k2>255) k2=0; break; case '-': --k2; if(k2<0) k2=255; } SetContrast(k2); gotoxy(30,14); cprintf("Key pressed %c",a); gotoxy(30,9); cprintf("Contrast %4d",k2); } textattr(WHITE+(RED<<4)); gotoxy(30,9); cprintf("Contrast %4d",k2); break; case 's': case 'S': gotoxy(30,10); cprintf("Saturation %4d",k3); while(((a=(char)getch())=='+')||(a=='-')) { switch(a) { case '+': ++k3; if(k3>255) k3=0; break; case '-': --k3; if(k3<0) k3=255; } SetSaturation(k3); gotoxy(30,14); cprintf("Key pressed %c",a); gotoxy(30,10); cprintf("Saturation %4d",k3); } textattr(WHITE+(RED<<4)); gotoxy(30,10); cprintf("Saturation %4d",k3); break; case 'b': case 'B': gotoxy(30,11); cprintf("Brightness %4d",k4); while(((a=(char)getch())=='+')||(a=='-')) { switch(a) { case '+': ++k4 ; if(k4>255) k4=0; break; case '-': --k4; if(k4<0) k4=255; } SetBright(k4); gotoxy(30,14); cprintf("Key pressed %c",a); gotoxy(30,11); cprintf("Brightness %4d",k4); } textattr(WHITE+(RED<<4)); gotoxy(30,11); cprintf("Brightness %4d",k4); break; case (char)27: ind2=0; break; default: a=getch(); break; } } ind=0; break; case 'N': case 'n': ind=0; break ; default: gotoxy(40,1); break; } } textattr((BLACK<<4)); clrscr(); textattr(WHITE+(BLUE<<4)); gotoxy(1,1); cputs("Do you wish to freeze image (y or n)-->"); while(((a=getch())!='y')&&(a!='n')); gotoxy(40,1); cprintf("%c",a); if(a=='n') { textattr(LIGHTGRAY+(BLACK<<4)); clrscr(); exit(1); } CaptureFrame(); SetInDispMode(); gotoxy(1,2); cputs( "DO You wish to save image on disk (y or n)-->"); while(((a=getch())!='y')&&(a!='n')); gotoxy(46,2); cprintf( "%c", a); if(a=='n') { textattr(LIGHTGRAY+(BLACK<<4)); clrscr(); exit(1); } gotoxy(1,3); cprintf("Enter name of fi I e to save image to ->"); scanf( "%s" , file_name); fptro=fopen( file_name,"wb"); gotoxy(70,25); textattr(WHITE+(GREEN<<4)+BLINK); cputs( "WAIT"); for(i=0;i<256;i++) { FGetPibRow(buff,0,511,i); fwrite(buff,512,2,fptro); } fclose(fptro); gotoxy(70,25); textattr(LIGHTGRAY+(BLACK<<4)); cputs(" "); clrscr(); } Để hiện thị màu bằng vỉ mạch VGA bạn có thể dùng chung bảng màu được phát triển cho hiện biểu đồ màu. Bảng màu này không phải là bảng màu tốt nhất cho tất cả các ảnh màu, và có thể tạo ra một bảng màu tối thiểu cho hiển thị ảnh. Một phép gần đúng cho phát triển bảng màu 8 bit (256 màu) cho các ảnh màu đặc biệt có thể mô tả bằng các bước sau đây: Giá trị ban đầu của bốn mảng, tất cả của 256 mức, đến giá trị không: palette.blue[256], palette.green[256], palette.red[256] palette.count[256] ở đây mỗi màu là một của bốn mảng số nguyên không dấu: đỏ, lục, lam, và số thứ tự. Quét toàn bộ ảnh và cho mỗi điểm màu: Nhân ba màu chính r, g, b với một hệ số hằng sao cho giá trị chỉ đến 255. Trong ảnh 5 bit /màu chính có nghĩa là dịch trái 3 bit (ví dụ giá trị lớn nhất cho màu chính là 31 ´ 8), hoặc bạn có thể chia khoảng cách giữa các giá trị sao cho màu chính với cường độ sáng lớn nhất nàm trong khoảng từ 0 đến 255. Tính cường độ chói dùng y = 0,59g + 0,30r + 0,11b, hoặc bạn có thể dùng công thức cho Y cho ở biểu thức (11.1). Làm tròn y đến giá trị nguyên gần nhất. Nếu giá trị làm tròn là k, thì tăng palette.count[k] thêm 1. Đặt n = palette.count[k] Tính palette.blue[k] = (n ´ palette.blue[k] + b)/(n + 1) palette.green[k] = (n ´ palette.green[k] + g)/(n + 1) palette.red[k] = (n ´ palette.red[k] + r)/(n + 1) ảnh màu có thể hiển thị như một ảnh mức cường độ sáng 8 bit tính dùng biểu thức độ chói và mục màu tính ra. Chú ý là ảnh màu cung cấp trong cuốn sách này có chiều rộng là 512, và chiều cao là 256 điểm. ảnh sẽ chỉ hiện lên cân xứng chỉ khi ta dùng vỉ mạch PIB ATI. Khi hiển thị ảnh dùng bộ chuyển đổi đồ hoạ video, để cho ảnh có tỷ lệ hợp lý, bạn cần chuyển ảnh có kích thước 256 ´ 256. Chương trình thực hiện chuyển đổi này lưu giữ trên đĩa trong file có tên là ATI_SCAL.C. ảnh có thể hiện lên dưới chế độ Microsoft Window bằng cách đầu tiên chuyển ảnh thành dạng bitmap cho Windows. Các file này thường có phần mở rộng là BMP. Chương trình dùng chuyển một ảnh màu thành file BMP được cung cấp trên đĩa dưới tên BIN2BMP.EXE. Một ảnh đã được chuyển đổi có thể được xem bằng chương trình Paintbrush của Windows. Chú ý rằng Windows phải ở chế độ hiển thị 256 màu. Thuộc tính này xuất hiện khi bạn nhắp đúp vào nhóm chương trình "Main" và sau đó nhắp đúp vào "Window Setup". Kích "Options", sau khi đã kích vào "Change System Settíng". Bạn cần đĩa Windows' video driver cho phép máy tính và vỉ mạch video chuyển sang chế độ mà bạn mong muốn. Một số chương trình dùng để hiển thị ảnh màu dưới DOS dùng vỉ mạch VGA cũng đã có sẵn trên đĩa. Đọc file README.DOC để hiểu thêm về các chức năng này. Chương trình hiển thị DOS sẽ hiển thị ảnh PIB ATI. Bạn sẽ cần chia hoặc biến đổi chúng theo dạng thích hợp cho window. Chương trình hiển thị DOS sẽ làm việc trên hệ thống của bạn nếu vỉ mạch video của bạn tuân theo tiêu chuẩn VESA. Nếu bạn có khó khăn trong hiện thị dưới môi trường DOS, bạn hãy dùng trong môi trường Windows được giải thích ở trên. Sẽ có một sự thay đổi rõ ràng chất lượng của ảnh hiện lên trên hệ thống có khả năng thể hiện 32,768 màu so với ảnh hiện lên trên hệ thống có khả năng thể hiện 256 màu. Để thấy rõ sự khác nhau này bạn cần chạy chương trình 11.4 để lấy và hiện lên các điểm ảnh trên vỉ mạch PIB, nếu vỉ mạch này đã được cung cấp sẵn cho hệ thống của bạn, hoặc bạn có thể thay đổi chương trình để thích hợp với vỉ mạch ảnh màu, nếu bạn có một sẵn một loại vỉ mạch khác. Bạn có thể dùng ảnh "IHABCOL.IMG" đã có sẵn trên đĩa với kích thước 512 ´ 512 điểm ảnh. Chương trình 11.4 "LOADPIB.C". Loading a Colored image on the PIB board. The image is assumed to be of size 512 x 256 pixels. /*This program is for loading a colored image stored in a file onto the PIB board.*/ #include #include #include #include void main() { int i ; char buff[1024], file_name[30]; FILE *fptri; clrscr(); InitPIB(); SetScreen(0); SetInDispMode(); SetInterlace(1); FillPibRect(0,0,0,511,255,0); printf("Enter name of file containing colored image-->"); scanf("%S",file_name); fptri=fopen(file_name,"rb"); if(fptri==NULL) { printf("file %s does not exist.\n"); exit(1); } for(i=0;i<256;i++) { fread(buff,512,2,fptri); FPutPibRow(buff,0,511,i); } fclose(fptri); } 11.6 Tín hiệu chói Tín hiệu chói của một ảnh màu dựa trên mức trắng và đen cơ bản của bức ảnh đó. Như chỉ dẫn trong phần 11.2, tín hiệu chói cho bởi Y = R + 4,5907G + 0,0601B (11.3) Biểu thức (11.3) thực sự tạo ra một ảnh đen trắng nếu chúng ta tạo ra một chương trình chuyển ảnh màu từ vỉ mạch PIB (512 ´ 256) sang ảnh độ chói. Chiều rộng ảnh độ chói là 256 ´ 256. ảnh độ chói được chia từ 0 đến 255 (8 bit). Mã của chương trình cung cấp ở chương trình 11.5. Chương trình 11.5 "COLTOBW.C".Transforming a color image acquired from the PIB board (512 x 256) to a luminance image suitable for display on the VGA card. /* program to convert color imagefrom PIB board (256x512) to gray-levelimage (256x256) which you can later display on your VGA card using DISP.C */ #include #include #include #include #include void main() { int R,G,B,i,j,buffi[512],yt; char ch,buffo[256],file_name[15]; float y; FILE *fptri,*fptro; clrscr(); printf("Enter name of file containing color image-->"); scanf("%s",file_name); fptri=fopen(file_name, "rb"); if(fptri==NULL) { printf("File %s does not exist",file_name); exit(1); } yt=wherey(); again: gotoxy(1,yt); delline(); printf("Enter name of file to store BW image-->"); scanf("%s",file_name); if(access(file_name,0)==0) { printf("File exists. Wish to overwrite? (y or n)-->"); while(((ch=tolower(getch()))!='y')&&(ch!='n')); putch(ch); switch(ch) { case 'y': break; case 'n': gotoxy(1,yt); delline(); goto again; } } fptro=fopen(file_name,"wb"); for(i=0;i<256;i++) { fread(buffi,1024,1,fptri); for(j=0;j<512;j+=2) { B=(0x001F & buffi[j]); G=(0x03E0 & buffi[j]) >> 5; R=(0x7C00 & buffi[j]) >> 10; y=R+4.5907*G+0.0601*B; ch=(char)(y*1.45568+0.5); /* ch=Y/Ymax*255.0 i.e. scale range between 0 to 255. */ /* Y=0.30*R+0.59*G+0.11*B; ch=(char)(Y*8.225806+0.5); */ buffo[j>>1]=ch; } fwrite(buffo,256,1,fptro); } fclose(fptri); fclose(fptro); } Hệ số nhân Y trong chương trình 11.5 được cho theo : Biến đổi này cho số mức nằm trong khoảng giữa 0 và 255. Chú ý rằng cho vỉ mạch PIB, số mức lớn nhất cho mỗi màu chính là 32. Một biểu thức nội suy cho độ sáng dùng để biến đổi tín hiệu truyền hình màu sang tín hiệu đen trắng: Y = 0,30R + 0,59G + 0,11B (11.4) Biểu thức này dựa theo cảm giác của mắt vào ba màu chính. Để kiểm tra chương trình 11.5 chúng ta sử dụng ảnh "IHABCOL.IMG". Kết quả dùng biểu thức (11.3) giới thiệu trong hình 11.7. Biểu thức (11.4) luôn cho một kết quả đúng, còn biểu thức (11.3) cho ta một ảnh mức xám có độ sáng tốt hơn. Để hoàn thiện kiến thức cơ bản của chúng ta về ảnh màu chúng tôi sẽ cung cấp cho bạn một chương trình dùng cho vỉ mạch PIB để hiển thị ba màu (đỏ, lục, lam) dưới dạng ảnh màu. Một ảnh sẽ được nạp vào vỉ mạch PIB trước tiên khi sử dụng LOADPIB. Hình 11.7 ảnh mức xám của ảnh "IHABCOL.IMG". Chương trình 11.6 “RGBCOMP.C”. Hiển thị một trong 3 màu chính của ảnh màu trên PIB. /*Program 11.6 "RGBCOMP.C". Program for displaying one of the three primary Image components of a color image on the PlB board. The color Image should be loaded first on the PIB board.*/ /* Program for producing r or g or b component image for a color image loaded on the PIB board. */ #include #include #include void main() { unsigned color,ch; int y; char file_name; clrscr(); printf("\nwhich image component would you like to see\n"); printf("Press r for red \n g for green\n b for blue\\n"); while(((ch=getch())!='r')&&(ch!='g')&&(ch!='b')); switch(ch) { case 'r': color=0xFC00; break; case 'g': color=0x83E0; break; case 'b': color=0x811F; } for(y=0;y<240;y++) FillPibRow(color,0,511,y,2); } Bạn có thể dùng chạy chương trình 11.6 trên "IHABCOL.IMG" để hiện ba khối màu chính, được cung cấp từ vỉ mạch PIB. Ba khối màu chính cũng giống như ảnh độ chói, ngoại trừ một được phủ bằng màu đỏ, một phủ bằng màu lam, một phủ bằng màu lục. 11.7 Lọc ảnh màu Không có gì khác nhau cơ bản giữa lọc một ảnh đen trắng và lọc một ảnh màu. Với ảnh màu chúng ta có thể thực hiện lọc bằng một trong hai phương pháp. Chúng ta có thể lọc ba màu chính như lọc một ảnh đen trắng, hoặc lọc ảnh độ chói sau đó sử dụng kết quả để đưa ra ảnh màu. Cả hai phương pháp này hoàn toàn đúng, tuy nhiên, phương pháp sau hay được dùng hơn vì một số lý do. Xử lý riêng ảnh độ chói thì bạn sẽ tiết kiệm được số phép tính toán, và nếu bạn dùng phần cứng cho lọc thời gian thực thì phương pháp này sẽ rất tiết kiệm phần cứng. 11.7.1 Lọc riêng ba màu chính Phương pháp này được trình bày như hình 11.8. Tất cả các màu chính được lọc riêng biệt, sau đó được khuyếch đại bù lại suy giảm do bộ lọc gây ra. Phương pháp này, nếu làm bằng phần cứng, sẽ đòi hỏi ba bộ lọc riêng biệt. ảnh màu Lọc màu đỏ Lọc màu Lọc màu lục Khuếch đại Khuếch đại Khuếch đại ảnh đã lọc Hình 11.8 Lọc riêng biệt ba màu chính. Bài tập 11.1 Lập một chương trình lọc ảnh màu dùng sơ đồ hình 11.8. Bộ lọc có thể là kiểu FIR hoặc là kiểu IIR, và không nhất thiết phải có cùng đáp ứng tần số, ví dụ, tín hiệu đỏ có thể lọc qua bộ lọc thông cao, tín hiệu lam qua bộ lọc thông thấp, và màu lục đi qua bộ lọc thông tất. Kiểm tra chương trình trên ảnh "AUTHOR.IMG" đã có sẵn trên đĩa. Dùng bộ lọc FIR thông cao được thiết kế theo kiểu xấp xỉ với tần số wc= 1.0 rad/đơn vị cho tất cả ba màu thành phần. 11.7.2 Lọc riêng ảnh tín hiệu chói Một tính chất của hỗn hợp màu (xem phần 11.2) là một điểm ảnh màu thì độc lập với độ chói của ảnh trên một phạm vi rộng. Dựa trên tính chất này, ta có thể lọc một ảnh màu mà không làm thay đổi các màu của nó. Vì vậy mà bộ lọc chỉ cho ra tín hiệu chói. ảnh đã được lọc tín hiệu chói có thể dùng để sửa lại mức của ba màu chính mà không thay đổi tỷ lệ R:G:B tại tất cả các điểm. Chương trình là cách giải thích tốt nhất cho sơ đồ hình 11.8. Cũng cần phải nói rằng các màu chính lấy ra đã được sửa lại mức tại tất cả các điểm bằng hàm khuyếch đại, hàm này rút ra bằng chia tín hiệu chói lấy ra cho các điểm mà ta đã lấy tín hiệu chói vào. Nếu như trong phương pháp trước, ba bộ lọc cho ba màu chính có đáp ứng tần số độc lập, thì phương pháp này sẽ cho kết quả gần như độc lập với phương pháp trước. Bài tập 11.2 Lập một chương trình C lọc ảnh màu dùng sơ đồ hình 11.9. Chú ý nếu Yi = 0.0, thì tín hiệu ra khỏi bộ lọc có R0 = G0 = B0 = 0.0. Kiểu bộ lọc có thể là FIR hoặc là IIR. 11.8 Lựa chọn hệ số sửa lại sắc màu và lọc Một vấn đề khó khăn trong xử lý ảnh màu là sửa lại sắc màu của một màu đặc biệt mà không làm ảnh hưởng các màu còn lại. Một phương pháp hay dùng đó là sửa lại các màu chính đến mức chính xác có thể, cùng lúc cân bằng các màu còn lại để hình ảnh có màu tự nhiên. Mặc dù, độ chính xác là sự cân bằng tất cả các sắc màu sao cho hình ảnh có màu sắc tự nhiên bằng các thay đổi ba sắc màu chính. Phương pháp lựa chọn thay đổi sắc màu của các màu đặc biệt mà không ảnh hưởng cân bằng màu với phần còn lại của ảnh. Phương pháp này gọi là thay đổi sắc màu có lựa chọn. Nó có khả năng làm tăng lên hoặc giảm đi một màu đặc biệt bằng cách dùng bộ lọc màu lựa chọn. Câu hỏi đặt ra là: Làm thế nào chúng ta có thể nhận ra sắc màu đặc biệt? Câu trả lời cho vấn đề này dựa theo biểu đồ màu. Một lớp màu được lấy ra bằng cách chia biểu đồ màu thành các miền màu, mỗi miền chứa một màu đặc biệt (xem hình 11.10). Trong hình 11.10, G = lục, Y = vàng, ST = skin tone´(amber), R = đỏ, M = đỏ tươi, B = lam, và C = xanh nước biển. Các đường thẳng (từ l0 đến l6) chia thành các màu dựa trên cảm giác của con người. Biểu thức của các đường thẳng này: (11.5) ở đây Pi(xi,yi) và {i = 0 đến 6} là điểm cho trong hình. Biểu thức cho các đường này có thể cho dưới dạng (11.6) Y1 ảnh đã lọc. Yo Sinh ra Y1=R + 4.5907G + 0.0601B Bộ lọc. Hình 11.9 Phương pháp chỉ lọc tín hiệu chói. G (0.2757, 0.7147) M B l6 l5 l4 l3 l2 l1 l0 (0.333, 0.333) W P5 (0.208, 0.285) P6 (0.229, 0.424) R(0.735, 0.265) P2(0.532, 0.465) P1(0.479, 0.517) P0(0.408, 0.585) P3(0.501, 0.160) P4(0.337, 0.086) B (0.167, 0.009) R G Y y x Hình 11.10 Phân chia màu sắc trong biểu đồ màu. ở đây mi và ci {i= 0 đến 6} cho trong bảng 11.2. Miền xung quanh điểm (0.333, 0.333), biểu diễn cho màu trắng trong sơ đồ màu, có thể xấp xỉ bằng một vòng tròn có bán kính r ằ 0,03. Chương trình cho phân chia lớp màu, tính giá trị R, G, B cho một điểm theo: 1. Tính X, Y, Z. 2. Tính x và y. 3. Tính: circ = (x - 0.333)2 + (y - 0.333)2 - r2 và cho {i = 0 đến 7} { tính : line = m[i]*x + c[i] - y nếu (line < 0) thì l[i] = 1 nếu không thì l[i] = 0 } Từ hình 11.10 ta có thể tính màu sắc của một điểm dựa trên giá trị bên trên của l[i]; {i = 0 đến 6} theo các bước: if (circ < 0) color = white else if (l[0]) = 1 and l[6] = 1) color = green else if (l[0]) = 0 and l[1] = 1) color = yellow else if (l[1]) = 0 and l[2] = 1) color = skin tone else if (l[2]) = 0 and l[3] = 1) color = red else if (l[3]) = 0 and l[4] = 1) color = magenta else if (l[4]) = 0 and l[5] = 1) color = blue else if (l[5]) = 1 and l[6] = 0) color = cyan Kết quả trên mô tả một lớp màu mà có thể dùng lựa chọn sửa lại sắc của một màu đặc biệt mà không làm ảnh hưởng đến các màu còn lại trên ảnh như sau: Chọn một sắc màu hoặc là các sắc màu mà bạn muốn sửa trên ảnh. Quét ảnh và dùng lớp màu để xác định liệu một điểm có thuộc về sắc màu đã được lựa chọn. Nếu một điểm không thuộc sắc màu lựa chọn, thì cho phép hiển thị thẳng lên màn hình mà không cần có một sự thay đổi nào. Dù thế nào đi chăng nữa, nếu nó thuộc về sắc màu lựa chọn, thì thay đổi đã được làm đối với điểm này là nó được phản xạ với sắc màu tự nhiên nhiều hơn. Các bước trên thể hiện trong hình 11.11. Lớp màu giới thiệu hình 11.11 cho giá trị 1 cho chỉ một trong số 7 đầu ra của sắc màu mà điểm ảnh này thuộc về, các đầu ra còn lại có giá trị 0. Tín hiệu ra của sắc màu lựa chọn là một mạch logic OR và làm chuyển mạch đường dẫn tín hiệu của điểm ảnh. Nó có thể đi qua bộ lọc sửa lại màu hoặc đi thẳng ra màn hình. Giải thuật này cho ở chương trình 11.7. Chương trình 11.7 "ADJUST.C " chương trình sửa lại sắc màu của một số sắc màu đặc biệt có lựa chọn. /* This program illustrastes the procedure for selective color adjustment for images using color tones derived from the chromaticity diagram. */ #include #include #include #include #include #include #define sqr(x) ((x)*(x)) ã ảnh điều chỉnh lựa chọn màu. ảnh màu vào 0 Lục Vàng Skin tone Đỏ Đỏ tươi Lam Xanh Bộ phân màu loại màu Hệ thống điều chỉnh màu hoặc bộ lọc 0 1 1 Hình 11.11 Điều chỉnh sắc màu có lựa chọn. #define white (circ<0) #define green (l[0]&&[16]) #define yellow ((!l[0])&&l[1]) #define skin_tone ((!l[1])&&l[2]) #define red ((!l[2])&&l[3]) #define magenta ((!l[3])&&l[4]) #define blue ((!l[4])&&(!l[5])) #define cyan (l[5]&&(!l[6])) #define condition (skin_tone||red)&&white) void main() { int i,j,n1,n2,image_width, image_length,dR,dG,dB,yt; int R1,G1,B1; char file_name[14],ch; unsigned int *buff,color,R,G,B; float Y,scale; float nsq,tmp; float X,Z,D,x,y; float m[]={3.3600, 1.260274, 0.663317, -1.029762, -61.75, 0.384, -0.875}; float c[]={-0.785880, -0.086671, 0.112116, 0.675911, 20.89575, 0.205128, 0.624375}; float r=0.025; float lt,circ; int l[7]; FILE *fptri, *fptro; clrscr(); printf("Enter file name for input image ->"); scanf("%s",file_name); if((fptri=fopen(file_name,"rb"))==NULL) { printf("%s does not exist.", file_name ); printf("\nPress any key to exit."); getch(); exit(1); } nsq=filelength(fileno(fptri))/2.0; printf("Is this a square image ?"); printf ("\n i.e. Is image_length=image_width (y or n)? -> "); while(((ch=(char)getche())!='y')&&(ch!='n')); switch(ch) { case 'y': image_length=image_width-sqrt(nsq); printf("\n Image size = %d x %d" , image_length, image_width); break; case 'n': printf("\nEnter image_width-->"); scanf("%d",&image_width); image_length=nsq/image_width; printf("Image length is %d", image_length); } yt=wherey(); again: gotoxy(1,yt+1); printf ("Enter file name for saving color adjusted image.-->"); scanf("%s",file_name); if(access(file_name,0)==0) { printf("File exists. Wish to overwrite? (y or n)-->"); while(((ch=tolower(getch()))!='y')&&(ch!='n')); putch(ch); switch(ch) { case 'y' : break; case 'n' : gotoxy(1,yt+1); delline(); goto again; } } fptro=fopen(file_name,"wb"); printf("\n For selected color tone(s) enter:"); printf("\n Change in Red primary ---->"); scanf("%d",&dR); printf("Change in Green primary-->"); scanf("%d",&dG); printf("Change in Blue primary --- >"); scanf("%d",&dB); buff=(unsigned int *)malloc(image_width*sizeof(int)); gotoxy(70,25); textattr(WHITE+(GREEN<<4)+BLINK); cputs("WAIT"); /* Algorithm */ for(n1=0; n1<image_length;n1++) { gotoxy(1,14); printf(" Transfered line %-4d. ",n1); /* Transfer row n1 of the image. */ fread(buff,sizeof(int),image_width,fptri); for(n2=0; n2<image_width; n2++) { color=buff[n2]; B= ( 0x001F & color); G= ( 0x03E0 & color) >> 5; R= ( 0x7C00 & color) >> 10; X=2.7690*R+1.7518*G+1.1300*B; Y=R+4.5907*G+0.0601*B; Z=0.0565*G+5.5943*B; D=X+Y+Z ; if(D==(float)0.0) continue; else { x=X/D; y=Y/D; circ=sqr(x-0.333)+sqr(y-0.333)-sqr(r); for(j=0;j<7;j++) { lt=m[j]*x+c[j]-y; if(lt<0) l[j]=1; else l[j]=0; } } if(condition) { R1=R; G1=G; B1=B; if((((R1+dR)>=0)&&((R1+dR)<=31))&& (((G1+dG)>=OM((G1+dG)<=31)&& (((B1+dB)>=0&&((B1+dB)<=31))) G1+=dG: B1+=dB; R=R1; G=G1; B=B1; } color=B+(G<<5)+(R<<10); buff[n2]=color; } } fwrite(buff,sizeof(int),image_width,fptro); } fclose(fptri); /* close input image file. */ fclose(fptro); /* close output image file. */ gotoxy(70,25); textattr(WHITE+(BLACK<<4)); cputs(" "); gotoxy(1,15); printf("Filtering is now completed."); } Trong chương trình 11.7 câu lệnh #define condition (skin_tone||red)&&(!white) định nghĩa vùng cần điều chỉnh trên ảnh. Tất nhiên bạn cũng có thể định nghĩa bất kỳ màu khác hoặc những màu sắc bạn muốn. Để minh hoạ chương trình bạn có thể sử dụng ảnh "AUTHOR.IMG". Bởi vì đây là một ảnh của chính tôi, tôi có thể nói chắc chắn với bạn rằng màu da sẽ sáng khi được hiển thị qua vỉ mạch PIB ATI. Hầu hết người Ai cập có nước da nâu nhạt và hơi đỏ. Nước da sẽ đen hơn nếu bạn đi về hướng nam Ai cập (vào châu Phi sâu hơn). Để chỉnh màu da, bạn có thể chạy chương trình trên với những tham số sau: thay đổi màu đỏ = 3; thay đổi màu xanh da trời = -1; thay đổi màu xanh lá cây = -1. Tất nhiên chương trình sẽ nhắc nhở bạn những số này. Kết quả cuối cùng sẽ được lưu trữ trên đĩa trong một file mà bạn định nghĩa lúc bắt đầu chương trình. Chú ý rằng chỉ có nước da và khu vực màu đỏ được chỉnh sửa, và những phần khác của ảnh không bị ảnh hưởng. Màu da rất giống với màu da tự nhiên của tôi. Nếu bạn muốn bạn có thể làm chương trình thể hiện sự liên hệ và cho phép thay đổi R,G,B thực hiện qua các phím mũi tên và các phím + và -, chương trình này đã được làm có tên DISPPIB.C. Chương trình 11.7 đồng nhất màu của mỗi điểm độc lập riêng biệt với các điểm lân cận của nó. Vì vậy một điểm bản thân nó không định nghĩa màu của khu vực, sẽ là tốt hơn khi lấy giá trị trung bình trên các điểm ảnh xung quanh điểm đó. Giá trị trung bình này dùng để đồng nhất lớp màu cho điểm đó. Phương pháp xấp xỉ được dùng để kiểm tra các điểm lân cận của mỗi điểm, và xác định rõ màu cơ bản của nó dựa trên các màu của những điểm lân cận. Ví dụ việc trộn giữa màu đỏ và xanh da trời cho ta màu nâu, đó không phải là màu cơ sở trong biểu đồ màu sắc. Bài tập 11.3 1. Lập một thuật toán xác định các màu không thấy trên sơ đồ màu từ các hỗn hợp màu tìm thấy trên sơ đồ màu. 2. Chuyển thuật toán thành chương trình C, dùng nó để thay đổi các sắc màu. 3. Kiểm tra chương trình của bạn trên ảnh “AUTHOR.IMG”. Có thể sẽ là tốt hơn nếu chúng ta có được sự phân lớp màu sắc. Rõ ràng là biểu đồ màu sắc chỉ cung cấp phân lớp thô của màu. Điều này sẽ rõ ràng nếu chúng ta nói về màu da mà dùng R, G, B phân biệt trên một ảnh hiển thị trên vỉ mạch PIB. Nếu sau đó chúng ta ánh xạ kết quả lên biểu đồ màu, chúng ta sẽ thấy màu chiếm giữ ở các khu vực màu vàng, màu xám da, và khu vực màu đỏ (giống như chương trình được cho ở chương 12). Nó không chiếm tất cả các khu vực như đã nói ở trước. Vì vậy, nếu đặt một sự phân lớp để nhận dạng dải màu trong khu vực, thì kết quả phân biệt mức xám sẽ tốt hơn. Như vậy phân biệt màu có thể học màu được biết như mạng thần kinh nhân tạo-chủ đề của chương 12.

Các file đính kèm theo tài liệu này:

  • docCHUONG11-Xử lý ảnh màu.DOC
Tài liệu liên quan