CHƯƠNG 2 : MỘT SỐ KIẾN THỨC LIÊN QUAN
2. Tổng quan về xử lý ảnh
2.6.1. Phân theo ngưỡng
Tham số θ được gọi là ngưỡng xám. Giả thiết rằng trong ảnh, đối tượng có màu sáng trên nền tối:
If a[m,n] ≥ θ Then a[m,n] := 1 { thuộc đối tượng} Else a[m,n] := 0 { thuộc nền}
Trong trường hợp đối tượng
If a[m,n] < θ Then a[m,n] := 1 { thuộc đối tượng} Else a[m,n] := 0 { thuộc nền}
Trong trường hợp I khơng phải là ảnh xám có thể sử dụng các đặc trưng khác. Ví dụ như
If (Redness{a[m,n]} ≥ θred.
Câu hỏi trung tâm của kỹ thuật phân theo ngưỡng là:
Chọn ngưỡng θ như thế nào?
1. Chọn ngưỡng cố định: Ngưỡng được chọn hoàn tồn độc lập với dữ liệu ảnh. Nếu ảnh có độ tương phản cao, đối tượng có mức sáng rất thấp, nền có mức sáng cao và đồng nhất thì hằng ngưỡng có thể chọn bằng 128.
2. Chọn ngưỡng theo brightness histogram: Ngưỡng có thể chọn từ brightness histogram của vũng ảnh hoặc tồn ảnh cần phân đoạn.
Trong hình 2.10, các điểm ảnh có giá trị bé hơn ngưỡng, a[m,n] < θ, thuộc về đối tượng, những điểm có giá trị lớn hơn ngưỡng thuộc về nền.
Một vài kỹ thuật chọn ngưỡng tự động từ các giá trị của brightness histogram, {h[b] | b = 0, 1, ... , 2B-1}.
Một số thuật toán thực hiện tốt trên một smoothing histogram thay vì raw histogram. Cơng thức chuyển đổi từ raw histogram sang smoothing histogram với W = 3 hoặc W = 5:
3. Thuật toán lặp (tác giả là Ridler and Calvard). Sử dụng ngưỡng ban đầu θ0 = 2B-1 để chia histogram thành hai phần. Ký hiệu (mf,0) là giá trị trung bình của các mức xám ở phần trước và (mb,0) là giá trị
trung bình của các mức xám ở phần sau. Giá trị ngưỡng mới θ1
được tính bằng trung bình cộng của (mf,0) và (mb,0). Thủ tục này được lặp cho đến khi nào ngưỡng không thay đổi, nghĩa là ở bước k nào đó θk = θk-1.
4. Thuật toán đối xứng nền – kỹ thuật này dựa trên cơ sở tính trội và cá biệt của đỉnh (trong histogram) tạo ra sự đối xứng trên nền. Kí hiệu maxp là giá trị lớn nhất trong histogram. Tính các điểm ảnh bên không thuộc đối tượng so với giá trị lớn nhất maxp. Giả sử p % là số điểm ảnh.
Trong hình 2.10, các điểm ảnh thuộc đối tượng nằm phái bên trái so với đỉnh (có giá trị 183), như vậy phải tìm ở bên phải so với đỉnh. Giá trị tìm được là 95%. Như vậy 5% số điểm ảnh có mức xám nằm bên phải ngồi cùng xuất hiện ở giá trị màu 216. Từ giả thiết đối xứng suy ra ngưỡng bằng 183 – (216 – 183) =150.
θ = maxp – { (p%) - maxp}
5. Thuật toán tam giác. Tác giả: Zack (1977). Đoạn thẳng nối điểm cao nhất trên histogram bmax với điểm thấp nhất bên trái bmin = (p=0)%. Khoảng cách lớn nhất d giữa đoạn thẳng [bmax, bmin] và giá trị histogram h[b] với b thay đổi trong khoảng b = bmin đến b =
bmax. Mức xám bo mà khoảng cách từ h[bo] đến đoạn thẳng [bmax,
3. Bộ lọc
3.1. Bộ lọc thresholding
Thresholding cho chúng ta một phương pháp về việc tách phần trong quá trình xử lý hình ảnh. Chúng ta cố gắng mơ tả phần đang hoạt động từ pixel của hình nền trong những ảnh ở định dạng 3 màu khác nhau. Chúng ta ít quan tâm những pixel hình nền và vì nguyên nhân này chúng ta có thể xem chúng như màu đen. Tuy nhiên, đối với phần đang hoạt động chúng ta phải đảm bảo chính xác màu cho ảnh nhập vào. Vì vậy, chẳng hạn một người hoặc một vật thể khác đang di chuyển trong hình ban đầu thì tồn bộ khung ảnh sẽ có màu đen trong ảnh đã được tạo ngưỡng ngoại trừ khu vực nơi người hoặc vật thể đó tồn tại. Người hay khối khác biệt này mô tả sự thay đổi được thể hiện trong hình ban đầu.
Nhưng làm thế nào mà thresholding có thể xác định được một pixel thuộc về phần hoạt động hay phần nền? Nói cách khác, nó được gán màu đen hay nên duy trì màu ban đầu của nó? Trong những ảnh màu, như là trong trường hợp của chúng ta, 3 ngưỡng sẽ được thiết lập cho việc đảm nhiệm 3 kênh màu. Mỗi kênh màu có một chuỗi các giá trị giữa 0 – 255, trong đó 0 biểu thị tình trạng khơng có màu đó và 255 biểu thị có đầy đủ màu đó. Trong thế giới tưởng tượng, khi khơng có những thay đổi ánh sáng, tiếng ồn và độ rung, tất cả sự tách biệt hình ảnh khơng cần thresholding. Sự khác biệt của những pixel trong các khu vực của cảnh đã thay đổi sẽ bằng 0 hoàn toàn. Nhưng trong thực tế, sự khác biệt của những pixel trong những điểm không thay đổi của ảnh sẽ khơng triệt tiêu hồn tồn và nó sẽ biểu thị những giá trị khơng phải là 0. Sự khác biệt của những pixel của những điểm trong cảnh thường thay đổi một cách rất lớn, bởi vì trạng thái của một vật thể bên ngoài thường thể hiện những giá trị cao hơn. Vì vậy chúng ta có hai sự phân loạin của các pixel màu sắc trên mỗi vùng màu của hình ảnh. Sự phân loại đầu tiên là nhóm những phần thấp hơn của
dãy 0 – 255 và mô tả những giá trị pixel màu chịu trách nhiệm cho những điểm nền. Sự phân loại thứ hai là nhóm những phần cao hơn của dãy 0 – 255 và mô tả những giá trị pixel màu chịu trách nhiệm cho những điểm trên phần hoạt động. Thơng thường có sự trùng lắp lên nhau giữa những sự phân tách phần nền và phần haọt động. Một thuật toán xác định ngưỡng tốt định vị điểm ngưỡng theo một cách mà cực tiểu vùng phân tách nằm trên khu vực ngưỡng của phía khác.
Một điều quan trọng để nhận ra rằng chúng ta chỉ biết những đối số của sự phân loại tổng số các pixel trên kênh màu. Ta giả sử rằng sự phân loại của màu nền và màu cảnh tồn tại trong phạm vi đó. Ta sẽ khơng thể biết một cách chính xác chúng là gì. Ta sẽ thử đốn bằng cách ước tính một giá trị tách rời chúng. Khi ta điều chỉnh threshold, ta sẽ tăng bề rộng của một phân loại và giảm những cái khác. Mục đích của chúng ta là thu thập threshold giảm đến mức tối thiểu bề rộng liên kết.
Ta có thể định nghĩa biến vithin-class σw2( )t để tác động lên tổng của
các biến của mỗi phân loại.
( )t w ( ) ( )t t w ( ) ( )t t w2 1 σ12 2 σ22 σ = + (3.3.4.1) Trong đó ( ) ∑ ( ) = = t l i P t w 1 1 (3.3.4.2) ( ) ∑ ( ) + = = N t l i P t w 1 2 (3.3.4.3) ( )t = 2 1
σ biến của những pixel trong sự phân loại nền (dưới threshold)
(3.3.4.4) ( )t =
2
(3.3.4.5) ( )t
w1 và w2( )t đại diện cho khả năng xảy ra phân loại màu nền và màu cảnh tương ứng. Những khả năng này được tính tốn bằng tổng những khả năng của các cường độ tương ứng. Trong từng trường hợp, cường độ riêng biệt P(i) được ước lượng bằng tỷ lệ số pixel có cường độ cao đối với tổng số pixel trong cảnh. Ta kí hiệu cường độ là N. Vì phạm vi của cường độ trên kênh màu là 0 – 255. Tổng số giá trị cường độ N=256.
Ta lấy biến tổng số pixel σ2 trừ biến lớp trong σw2( )t ta được biến lớp
giữa σb2( )t . ( ) σ σ ( ) (µ µ) (µ µ) σ = − = − 2 + 2 2 − 1 1 2 2 2 t w t w w b (3.3.4.6) Trong đó: µ : Tổng số. 1
µ : Sự phân bố pixel màu nền.
2
µ : Sự phân bố pixel màu cảnh.
Những giá trị trung bình có thể tính bằng những phương trình dưới đây. ( )t M1( ) ( )t w1 t 1 = / µ (3.3.4.7) ( )t iP( )i M t i ∑ = = 1 1 (3.3.4.8) ( )t M2( )t w2( )t 2 = / µ (3.3.4.9) ( ) ∑ ( ) + = = N t i i iP t M 1 2 (3.3.4.10) ( ) ∑ ( ) = = N i i iP t 1 µ (3.3.4.11) Chúng ta sử dụng phương trình (3.3.4.11) để tính tổng trung bình. Bằng cách xem xét cẩn thận phương trình (3.3.4.6), chú ý rằng biến lớp giữa bản thân nó chỉ đơn giản là biến biểu thị giá trị phân bố trung bình
trên giá trị trung bình tồn bộ. Việc cực đại biến lớp trong có thể có được khi làm cực đại biến lớp giữa. Chúng ta kết hợp phương trình (3.3.4.7) và (3.3.4.11) vào phương trình (3.3.4.6) sẽ được:
( ) ( ( ) ( )( )( ( )( )) ) t w t w t M t t w t b 1 1 2 1 1 2 1− − = µ σ (3.3.4.12)
Với mỗi giá trị ngưỡng t (t∈[0−255] ) ta tính giá trị (có thể có) của phân bố nền w1 và giá trị trung bình M1. Chúng ta sử dụng những giá trị này để tính biến lớp giữa cho mỗi cường độ pixel t. Sau đó, chúng ta chọn một giá trị ngưỡng tốt nhất để làm cực đại 2
b
σ . Việc này có vẻ khó khăn nhưng may mắn thay chúng ta có thể nắm bắt chính xác được tiến trình này. Chúng ta có thêr bắt đầu từ t = 0 và tăng dần w1 và M1 đến khi t = 255 bằng cách sử dụng phương trình dưới đây.
( 1) 1( ) ( 1) 1 t+ =w t +Pt+ w (3.3.4.13) (t ) w( ) (t t ) ( )Pt M +1 = 1 + +1 (3.3.4.14) Chúng ta sử dụng phương trình (3.3.4.13) và (3.3.4.14) để tăng dần 1
w và M1 tại mỗi bước. Dựa trên giá trị này và giá trị trung bình tổng µ
chúng ta tính biến lớp giữa bằng cách áp dụng ngay phương trình (3.3.4.6). Chúng ta so sánh giá trị tại bước hiện hành của biến lớp giữa với giá trị cực đại ở những bước trước. Sau kết quả của phép so sánh này ta luôn lưu lại giá trị cực đại của biến lớp giữa cùng với giá trị cường độ nơi mà nó diễn ra. Hàm GetImageThreshold trả lại giá trị cường độ mà tạo nên giá trị cực đại biến lớp giữa. Đây là giá trị ngưỡng tách biệt giữa màu nền và màu cảnh theo một kênh màu nhất định (RED, GREEN hoặc BLUE).
3.2. Bộ lọc Difference
Bộ lọc Diference lấy sự khác nhau giữa source image và Overlay Image. Tuy nhiên, Overlay Image và source image phải có cùng kích thước
kiểm tra xem mỗi pixel ảnh biểu diễn bằng bao nhiêu byte. Khi kiếm tra thấy thỏa mãn đầy đủ điều kiện trên ta tiến hành so sánh từng pixel ảnh với nhau, việc làm này giúp ta biết được sự sai khác giữa hai ảnh liên tiếp với nhau. Trong ứng dụng quan sát căn cứ vào tỷ lệ sự sai khác đó mà ta có thể đưa ra quyết định báo động hay khơng. Dưới đây là thuật tốn thể hiển ý tưởng này:
Thuật toán Difference:
Bước 1:
If (imageSource.PixelFormat != overlayImage. PixelFormat) {
Writeln(“imageSource và overlayImage phải có cùng PixelFormat”);
}
Bước 2:
Int width = imageSource.Width; Int height = imageSource.Height;
If ((width != overlayImage. Width) or (height != overlayImage. Height))
{
Writeln(“Kích thước overlayImage phải bằng imageSource”);
}
Bước 3:
Kiểm tra xem ảnh là ảnh xám hay ảnh.
Bước 4:
Thực hiện so sánh sự sai khác bằng cách tính hiệu hai giá trị trên hai pixel tương ứng với hai ảnh.
3.3. Bộ lọc ReplaceChannel
Bộ lọc ReplaceChannel có chức năng Replace màu lên đối tượng di chuyển. Trong bộ lọc này ta tạo thuộc tính Channel, thuộc tính này cho phép chọn kênh màu là Red, Green hay Blue để Replace. Tùy theo mục đích sử dụng hay chức năng ta lựa chọn kênh màu Replace cho phù hợp. Thuộc tính Channel được xây dựng như sau:
public short Channel {
get { return channel; } set { if ( ( value != RGB.R ) and ( value != RGB.G ) and ( value != RGB.B ) ) { Writeln(“ Error”); } channel = value; } }
Vì ảnh Replace chỉ cho phép lựa chọn một kênh màu đầu vào do đó định dạng pixel của ảnh có dạng Format8bppIndexed. Ảnh Replace phải phù hợp với ảnh nguồn về kích thước nghĩa là có cùng chiều rộng và chiều cao. Thuật tốn mơ tả ý tưởng trên như sau:
Int width = imageSource.Width; Int height = imageSource.Height;
If ((width != replaceImage.Width) or (height != replaceImage. Height))
{
Writeln(“Kích thước replaceImage khơng phù hợp với imageSource”);
}
Bước 2:
For (int i = 0; i < height; i++)
For (int x = 0; x < width; x++) {
imageSourcePixel = replaceImagePixel; }
3.4. Bộ lọc ExtractChannel
Bộ lọc ExtractChannel gồm có dữ liệu ảnh đầu vào và dữ liệu ảnh đầu ra, ảnh đầu ra là kết quả của ảnh đầu vào với định dạng kênh màu ta lựa chọn. Trong lớp của bộ lọc này ta cũng tạo thuộc tính Channel, thuộc tính này cho phép chọn kênh màu là Red, Green hay Blue. Tùy theo mục đích sử dụng hay chức năng ta lựa chọn kênh màu cho phù hợp. Trong ứng dụng cài đặt chúng ta chọn giá trị mặc định là RGB.R. Thuộc tính Channel được xây dựng như sau:
public short Channel {
get { return channel; } set
if ( ( value != RGB.R ) and ( value != RGB.G ) and ( value != RGB.B ) ) { Writeln(“ Error”); } channel = value; } }
Do ảnh đầu ra là kết quả của ảnh đầu vào với kênh màu ta lựa chọn nên ta không cần kiểm tra xem ảnh đầu ra có cùng định dạng hay cùng kích thước với ảnh đầu vào hay khơng. Ta dùng một biến con trỏ kiểu byte để trỏ đến pixel đầu tiên trong ảnh đầu vào sau đó cộng nó với kênh màu ta lựa chọn. Thuật tốn mơ tả ý tưởng trên như sau:
Thuật toán ExtractChannel:
Bước 1:
int width = sourceData.Width; int height = sourceData.Height;
Bước 2:
byte * src = (byte *) sourceData.Scan0.ToPointer( ); byte * dst = (byte *) destinationData.Scan0.ToPointer( ); //
src += channel;
for ( int x = 0; x < width; x++) { *dst = *src; } } 3.5. Bộ lọc merge
Bộ lọc Merge thực hiện lấy giá trị Max giữa hai pixel trên hai ảnh. Giả sử, ta có ImageSource và ImageOverlay khi đó ta thực hiện quét trên từng pixel của hai ảnh và so sánh, nếu giá trị pixel của ảnh ImageOverlay lớn hơn giá trị pixel của ảnh ImageSource thì gán pixel của ảnh ImageSource bằng giá trị pixel của ảnh ImageOverlay so sánh đó. Tuy nhiên, ảnh ImageOverlay và ảnh ImageSource phải có cùng định dạng tức là:
ImageSource.PixelFormat != ImageOverlay.PixelFormat
Để thực hiện so sánh trên hai ảnh ta dùng hai biến con trỏ để quét trên từng pixel của hai ảnh. Ban đầu ta cho nó trỏ đến địa chỉ của pixel đầu tiên trên hai ảnh như sau:
byte * ptr = (byte *) ImageSource.Scan0.ToPointer( ); byte * ovr = (byte *) ovrData.Scan0.ToPointer( );
Mặt khác, ta cũng cần xác định tọa độ canh theo trục X và theo trục Y của ảnh ImageOverlay. Khi hai ảnh có cùng kích thước và tọa độ canh theo trục X và theo trục Y bằng 0 thì ta tiến hành so sánh, nếu một trong các điều kiện khơng thỏa mãn thì ta phải tiến hành kiểm tra theo từng trục X và Y để định lại kích thước cho ảnh ImageOverlay rồi tiến hành so sánh lấy giá trị Max của pixel ảnh.
Thuật toán Merge:
Bước 1: Kiểm tra xem có cùng định dạng
{
Writeln(“Hai anh phai co cung PixelFormat”); }
Bước 2: Lấy lích thước ảnh và một số thông số khác
// Lay kich thuoc anh
int width = ImageSource.Width; int height = ImageSource.Height; // Kich thuoc va vi tri ImageOverlay int ovrX = overlayPosition.X;
int ovrY = overlayPosition.Y; int ovrW = ImageOverlay.Width; int ovrH = ImageOverlay.Height; // Khoa anh ImageOverlay
BitmapData ovrData = overlayImage.LockBits(…, …., …); // Lay kich thuoc cua pixel
pixelSize = (ImageSource.PixelFormat ==
PixelFormat.Format8bppIndexed ) ? 1 : 3;
Bước 3: Khởi tạo 2 biến con trỏ
byte * ptr = (byte *) ImageSource.Scan0.ToPointer( ); byte * ovr = (byte *) ovrData.Scan0.ToPointer( );
Bước 4: Thực hiện so sánh
if ( ( width == ovrW ) and ( height == ovrH ) and ( ovrX == 0 ) and ( ovrY == 0 ) )
{
{
for ( int x = 0; x < lineSize; x++) { if ( *ovr > *ptr ) *ptr = *ovr; } } }
Bước 5: Bước 4 không thỏa mãn ta kiểm tra theo các trục X và Y rồi định lại kích thước ảnh ImageOverlay và thực hiện so sánh
if ( ovrY >= 0 ) ……… else ……… // if ( ovrX >= 0 ) ……… else ………
// cap nhat chieu rong va chieu cao
ovrW = Math.Min( ovrW, width - ovrX ); ovrH = Math.Min( ovrH, height - ovrY ); if ( ( ovrW > 0 ) and ( ovrH > 0 )
and ( ovrX < width ) and ( ovrY < height ) ) {
lineSize = pixelSize * ovrW; for ( int y = 0; y < ovrH; y++ ) {
for ( int x = 0; x < lineSize; x++ ) { if ( *ovr > *ptr ) *ptr = *ovr; } } }
Trên đây là một số thuật toán và ý tưởng xây dựng các bộ lọc phục vụ cho xây dựng các lớp bắt đối tượng di chuyển trong chương 3.
CHƯƠNG 3: XÂY DỰNG LỚP PHỤC VỤ CHO BẮT ĐỐI TƯỢNG DI CHUYỂN
Trước khi bắt tay vào xây dựng các Class phát hiện đối tượng di chuyển chúng ta nên tạo một Class interface để từng Class sau đó kế thừa. Trong Class này ta định nghĩa hai thuộc tính và hai phương thức ở cấp độ tổng quan và sau đó căn cứ vào mục đích và nhiệm trong từng Class kế thừa mà định nghĩa lại. Trong ứng dụng này ta định nghĩa tên Class interface là Detector, trong đó ta định nghĩa hai thuộc tính MotionLevelCalculation(tính tốn cấp độ thay đổi) và MotionLevel(cấp độ chuyển động – số phần trăm thay đổi), hai phương thức ProcessFrame(xử lý hình ảnh) và Reset(khởi tạo lại Detector với trạng thái đầu). Sau đây