KHỐI XỬ LÝẢNH YUV 2.1SƠ ĐỒ KHỐI Hình 10.1: Sơ đồ của khối xử lýảnh YUV Tên Mô tả CLK Xung clock 27Mhz từ kit DE2. RESET Reset hệ thống. mYCbCr_d[15:0] Dữ liệu hình ảnh ngõ vào. oRequest Tín hiệu điều khiển do VGA Controller cung cấp: yêu cầu xuất dữ liệu. iX[0] Tín hiệu điều khiển do VGA Controller cung cấp, cho biết vị trí của Pixel l chẵn hay lẻ (bit 0 trong gi trị của bộ đếm vị trí Pixel) oRequest Tín hiệu điều khiển do VGA Controller cung cấp: yu cầu xuất dữ liệu. iYCbCr Pixel ảnh sau qua Image Process xử lý. oY[7:0] Thành phần độ sáng (Luma) của Pixel được tách ra. oCb[7:0] Thành phần Cb của Pixel được tách ra. oCr[7:0] Thành phần Cr của Pixel được tách ra. Resgister[1 9][15:0] 9 thanh ghi tương ứng với cửa sổ 3x3 pixels. 2.2 MÔ TẢ Khối Line Buffer: là bộ đệm để lưu lại các giá trị các Pixel cần thiết. Xét cửa sổ 3x3 Pixel: trong chuỗi dữ liệu ngõ vào vị trí các pixel này như sau: Để cửa pixel này xuất hiện cùng lúc trong 1 cửa sổ thì phải cần có các bộ đệm ( các thanh ghi và line buffer) để lưu lại các giá trị của P1, P2, P3, P4, P5, P6, P7, P8 cho đến khi P9 xuất hiện: Hình 10.2: sử dụng các Line_Buferr và Regitster để tạo cửa sổ 3x3 pixel Line_Buffer có thể là 1 FIFO hoặc là 1 thanh ghi dịch(shift register), nhưng trong thư viện của Quartus không có FIFO với chiều dài 640 Words, nên ta sử dụng thanh ghi dịch: Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo custom mới, đặt tên là Line_Buffer, chọn phần Memory Compiler >> shift register ( RAM-Based). Ta chọn độ rộng dữ liệu là 8bits, chiều dài (distance between Taps) là 640, số Tap là 1, và đánh dấu chọn để sử dụng chân clock enable. Như vậy ta được cửa sổ Pixel: Khốixửlý ảnh: Ta chọn 1 trong hai chế độ làm việc: lọc trung bình và tách biên. • Lọc trung bình: Thực hiện phép tương quan cửa sổ pixel với mặt nạ Tuy nhiên dữ liệu vào là 16 bit với 8 bit cao là thành phần Y và 8 bit thấp là Cb hoặc Cr. Nên ta sử dụng khai báo để tách ra từng thành phần rồi xử lý: Loc_trung_binh Loc_trung_binh_0 ( clock, reset, register1[7:0], register2[7:0], register3[7:0], register4[7:0], register5[7:0], register6[7:0], register7[7:0], register8[7:0], register9[7:0], out2 ); Loc_trung_binh Loc_trung_binh_1 ( clock, reset, register1[15:8], register2[15:8], register3[15:8], register4[15:8], register5[15:8], register6[15:8], register7[15:8], register8[15:8], register9[15:8], out1 ); Để thực hiện phép tương quan giữa cửa sổ Pixel với mặt nạ lọc, ta tiến hành theo các bước: Nhân các thành phần tương ứng của 2 cửa sổ lại với nhau: mặt nạ lọc chỉ có các hệ số 1, 2, 4 (dễ thấy kết quả là các số 10 bit ) k = 1 thì giữ nguyên: multi_1 <= { 2'b00, register1}; k = 2 thì dịch trái 1 bit : multi_2 <= { 1'b0, register2,1’b0}; k = 4 thì dịch trái 2 bit: multi_5 <= { register5,1’b00}; Lấy tổng các tích vừa tìm được (tổng này là 12 bit): assign multi1 = multi_1 + multi_3 + multi_7 + multi_9; assign multi2 = multi_2 + multi_4 + multi_6 + multi_8; assign multi = multi1 + multi2 + multi_5; Chia tổng trên cho 16 tương đương với việc lấy 8 bit cao: assign out = multi[11:4]; • Tách biên: Tương tự như trên ta cũng tách dữ liệu 16 bit ra từng thành phần để xửlý với các bước thực hiện như sau: a) Tính |G x | và |G y |: Chập ma trận cửa sổ 3×3 pixels ảnh của frame với hai mặt nạ lọc theo phương pháp gradient với măt nạ lọc Prewitt : Mặt nạ lọc chỉ có các hệ số 0, 1, 2 , -1 và -2 ( k =1, 2 đã xét ở phép lọc trung bình) k = 0 thì multi <= 0; k =-1 thì lấy bù 2: multi = ~{3'b000,register} + 1; k = -2 dịch trái 1 bit rồi lấy bù 2: multi = ~{2'b00,register,1'b0}+1; Với register [7:0] nhân với số [1:0] -> số [9:0] thêm bit dấu thành số [11:0], tức là 12 bits. Sau đó cộng tất cả các thành phần của cửa sổ thu được rồi lấy 8 bit cao trong giá trị tuyệt đối ta có kết quả là |Gx| và |G y| b) Tính giá trị ngõ ra của pixel theo cơng thức G = √ G x 2 +G y 2 Tính giá trị bình phương của G x và G y với bộ nhân từ thư viện của Quartus: Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo custom mới, đặt tên là MULT2, chọn phần Arithmetic >> LPM_MULT. Chọn độ rộng bit ngõ vào là 8 bit. Sau khi tổng hợp ta được một khối với khai báo như sau: module MULT2 ( dataa, datab, result); Để lấy phép bình phương ta nhập cùng một giá trị cho 2 ngõ vào dataa và datab. Dùng bộ lấy căn bậc 2 từ thư viện của Quartus để tính G từ tổng hai kết quả trên: Phần Menu >> Tools >> MegaWizard Plug_in Manager… >> Create … tạo custom mới, đặt tên là SQUARE, chọn phần Arithmetic >> ALTSQRT. Chọn độ rộng bit ngõ vào là 16 bit.Sau khi tổng hợp ta được một khối với khai báo như sau (trong đó radical là dữ liệu 17 bit ngõ vào, q là kết quả 9 bit của phép lấy căn, ta không sử dụng chân remainder): module SQUARE ( radical, q, remainder); Thực chất khốixửlýảnh chỉ là các cặp khối lọc biên, lọc trung bình được ghép song song nhau. Mỗi khối trong cặp xửlý trên từng 8 bit dữ liệu, sau đó ghép chúng lại với nhau (out3, out 4 tương tự là các ngõ ra của các khối lọc biên) assign out_pixel = (!reset)? 16'b0 : out; assign out = select_process? {out1,out2} : {out3,out4}; Khối sẽ xuất ra giá trị của pixel ảnh tương ứng với giá trị pixel ảnh nằm chính giữa cửa sổ. Có 1 vấn đề được đặt ra ở đây là khi một frame vừa bắt đầu thì cửa sổ chưa có đủ 9 Pixel nhưng bộ xửlýảnh vẫn thực hiện lọc và xuất pixel sẽ dẫn đến sai số ở biên ảnh. Đồng thời khối Image Process cần có 1 số chu kỳ xung clock để xửlý xong ảnh. Tuy nhiên với 1 frame kích thước 640 x 480 thì các sai lệch này có thể chấp nhận được. Khối Extract YCrCb to Y, Cr, Cb : đơn giản chỉ là tách chuỗi dữ liệu 16 bit dạng YCrCb liên tiếp ra 3 thành phần Y, Cr, Cb. Dựa vào tín hiệu iX[0] do VGA controller đưa ra để biết vị trí của Pixel trong hàng là chẵn hay lẻ(16 bit này là YCb hay là YCr): if(iX[0]) {mY,mCr} <= iYCbCr; else {mY,mCb} <= iYCbCr; Như vậy dữ liệu 16 bit ngõ vào đã được xửlý và tách ra 3 thành phần Y, Cr, Cb. . KHỐI XỬ LÝ ẢNH YUV 2.1SƠ ĐỒ KHỐI Hình 10.1: Sơ đồ của khối xử lý ảnh YUV Tên Mô tả CLK Xung clock 27Mhz từ kit. remainder); Thực chất khối xử lý ảnh chỉ là các cặp khối lọc biên, lọc trung bình được ghép song song nhau. Mỗi khối trong cặp xử lý trên từng 8 bit dữ