1. 3.2 Các khái niệm và qui ước trong Image Processing Toolbox
2.1 Phương pháp nghiên cứu
Bước 1: Thu nhận ảnh Bước 2: Tiền xử lý ảnh Bước 3: Phân ngưỡng
Bước 4: Khử nhiễu và tách đối tượng Bước 5: Xuất tín hiệu điều khiển robot 2.2 Nội dung nghiên cứu
2.2.1 Thu nhận ảnh
Dùng Image Acquisition Toolbox của MatLab để thu thập ảnh số từ các thiết bị thu hình.
Cụ thể được thực hiện theo các bước sau:
Bước 1: Gắn thiết bị thu hình vào máy tính và cài đặt driver điều khiển
+ Gắn thiết bị thu hình vào máy tính.
+ Cài đặt driver (trình điều khiển) cho thiết bị (được cho bởi nhà sản xuất).
+ Xem thử hình ảnh video hiện trên máy tính thông qua phần mềm của nhà sản xuất.
+ Khởi động MatLab
Bước 2: Chỉ định thông tin phần cứng:
Ta cần chỉ định cho MatLab biết phần cứng nào dùng để lấy dữ liệu (vì có thể có nhiều camera kết nối tới PC)
Gõ lệnh imaqhwinfo để biết tên các loại thiết bị có thể dùng.
>> imaqhwinfo ans =
InstalledAdaptors: {'coreco' 'winvideo'} MATLABVersion: '7.6 (R2008a)'
ToolboxName: 'Image Acquisition Toolbox' ToolboxVersion: '3.1 (R2008a)'
Tên Loại thiết bị
'coreco' Thiết bị của công ty coreco
‘DCAM’ Các thiết bị dùng chuẩn IEEE 1394 ‘dt’ Các thiết bị của Data Translation ‘Matrox’ Các thiết bị của hãng Matrox
‘winvideo’
Các thiết bị dùng chuẩn Windows Driver Model (WDM) hoặc Video for Windows (VFW). Bao gồm các loại USB WEBCAM và camera IEEE 1394
* Chỉ định thiết bị: Tuỳ vào loại thiết bị (adaptor name), mỗi thiết bị cùng loại gắn vào PC được đánh số ID, thiết bị thứ nhất có deviceID=1, thiết bị thứ 2 có deviceID=2, v.v…
Để liệt kê xem loại winvideo có bao nhiêu thiết bị gắn vào máy, ta cũng dùng lệnh imaqhwinfo với đối số là winvideo
>> imaqhwinfo('winvideo') ans = AdaptorDllName: [1x81 char] AdaptorDllVersion: '3.1 (R2008a)' AdaptorName: 'winvideo' DeviceIDs: {[1] [2]} DeviceInfo: [1x2 struct]
=> Có một thiết bị với DeviceID là 1. Để tìm hiểu thêm thông tin về thiết bị này:
>> imaqhwinfo('winvideo',1) ans =
DefaultFormat: 'YUY2_160x120' DeviceFileSupported: 0
DeviceName: 'USB Video Device' DeviceID: 1
ObjectConstructor: 'videoinput('winvideo', 1)' SupportedFormats: {1x5 cell}
Bước 3: Tạo đối tượng đại diện cho luồng dữ liệu video
Để tạo luồng dữ liệu video, bạn dùng lệnh videoinput. Ví dụ
>> vid = videoinput('winvideo',1)
Summary of Video Input Object Using 'USB Video Device'. Acquisition Source(s): input1 is available.
Acquisition Parameters: 'input1' is the current selected
source.
10 frames per trigger using the selected source.
'YUY2_160x120' video data to be logged upon START.
Grabbing first of every 1 frame(s). Log data to 'memory' on trigger.
Trigger Parameters: 1 'immediate' trigger(s) on START.
Status: Waiting for START.
0 frames acquired since starting. 0 frames available for GETDATA.
Bước 4: Hiển thị luồng video trên màn hình để xem thử (tuỳ chọn)
Sau khi tạo biến tham chiếu luồng video (MatLab gọi là tạo đối tượng video
ngõ vào), Ta có thể dùng MatLab để lấy dữ liệu từ thiết bị thu hình (thu thập dữ
liệu).
Tuy nhiên, trước khi làm việc này, ta có thể xem trước luồng video để đảm bảo thiết bị hoạt động tốt (để điều chỉnh độ sáng, độ tương phản, độ hội tụ v.v…). Để xem trước luồng dữ liệu video, ta dùng lệnh preview. Ví dụ:
>> preview(vid)
Hình 2.2: Cửa sổ preview
Màn hình lúc này hiện lên cửa sổ video của đối tượng vid. Để kết thúc xem, dùng lệnh stoppreview. Hoặc để đóng cửa sổ preview, dùng lệnh
closepreview(vid)
Bước 5: Cấu hình cho hoạt động trích hình ảnh (tuỳ chọn)
Một số thông số hoạt động của biến video mà bạn có thể thay đổi. Trước tiên, ta phải hiểu là có 2 đối tượng tác động khác nhau khi bạn tạo biến video.
+ Video input objects: Đối tượng này đại diện cho các thông tin kết nối phần cứng.
Nó được tạo bằng lệnh videoinput ở bước 3.
Để xem thông tin các thuộc tính của đối tượng video (Video input objects) ta dùng lệnh get(biến đối tượng video)
>> get(vid) General Settings: DeviceID = 1 DiskLogger = [] DiskLoggerFrameCount = 0 EventLog = [1x0 struct] FrameGrabInterval = 1 FramesAcquired = 0 FramesAvailable = 0 FramesPerTrigger = 10 Logging = off LoggingMode = memory Name = YUY2_160x120-winvideo-1 NumberOfBands = 3 Previewing = off ROIPosition = [0 0 160 120] Running = off Tag = Timeout = 10 Type = videoinput UserData = [] VideoFormat = YUY2_160x120 VideoResolution = [160 120] Color Space Settings:
BayerSensorAlignment = grbg ReturnedColorSpace = YCbCr
Callback Function Settings: ErrorFcn = @imaqcallback FramesAcquiredFcn = [] FramesAcquiredFcnCount = 0 StartFcn = [] StopFcn = [] TimerFcn = [] TimerPeriod = 1 TriggerFcn = [] Trigger Settings: InitialTriggerTime = [] TriggerCondition = none TriggerFrameDelay = 0 TriggerRepeat = 0 TriggersExecuted = 0 TriggerSource = none TriggerType = immediate Acquisition Sources: SelectedSourceName = input1 Source = [1x1 videosource]
Hoặc để biết luồng dữ liệu hiện thời (luồng dữ liệu được chọn để xử lý) ta dùng lệnh getselectedsource(đối tượng video). Và do đó, ta thường dùng lệnh sau để biết thông số của luồng dữ liệu hiện thời:
>> get(getselectedsource(vid))
Trong các thông số này, có một số là chỉ đọc (read only), một số ta có thể thay đổi được. Để thay đổi thông số mong muốn, ta dùng lệnh set. Cấu trúc lệnh set thông thường giống như khi ta tạo GUI. Ví dụ lệnh sau:
>> set(vid,'TriggerRepeat',Inf);
Hoặc ta có thể thiết lập thông số bằng cách xem biến video như một biến kiểu cấu trúc. Ví dụ:
>> vid.FrameGrabInterval = 5;
+ Video source objects: Khi bạn tạo video inut object, MatLab tự động tạo thêm
đối tượng “video source object” và liên kết nó với video input object. Đối tượng
này đại diện cho luồng dữ liệu hình ảnh. Có thể tạo nhiều “video source object” trên một thiết bị phần cứng, nhưng tại một thời điểm thì chỉ có một được chọn để xử lý. Để thiết lập giá trị cho Video source objects, ta phải đặt một biến đại diện thông qua lệnh getselectedsource. Ví dụ:
>> vid_src = getselectedsource(vid)
Display Summary for Video Source Object: Index: SourceName: Selected: 1 'input1' 'on'
>> set(vid_src,'Tag','motion detection setup');
Bước 6: Lấy dữ liệu hình ảnh
Ta tiến hành theo các bước sau để lấy dữ liệu:
+ Gọi hàm start để bắt đầu. (ví dụ : Start(vid)) . Một số thông số của biến video sẽ bị khoá thành dạng chỉ đọc.
+ Lấy dữ liệu (hay còn gọi là thu thập dữ liệu): Tuỳ vào thông số TriggerType, ta có nhiều cách lấy dữ liệu.
Ví dụ: ta thiết lập TriggerType là immediate thì MatLab tự động lấy dữ liệu
chuyển vào bộ đệm ngay sau lệnh start. Nếu ta thiết lập là manual, MatLab chờ lệnh gọi trigger (lệnh này phải được gọi sau khoảng thời gian khởi tạo)
+ Đem dữ liệu trong bộ đệm đi tính toán hoặc sử dụng: Dữ liệu thu thập được sau khi trigger nằm ở bộ đệm hay ở đĩa cứng, hay cả hai tuỳ vào thông số LoggingMode. Để đem dữ liệu này vào workspace, ta dùng lệnh getdata.
Bước 7: Làm sạch bộ nhớ
Sau khi lấy dữ liệu video, ta có thể giải phóng bớt bộ nhớ bằng các lệnh sau:
>> clear >> close(gcf)
2.2.2 Tiền xử lý ảnh
Thực hiện các phép biến đổi ảnh để nâng cao chất lượng ảnh nhằm giảm bớt sai số trong quá trình xử lý tiếp theo.
2.2.2.1 Lọc tuyến tính
Ta xét một ví dụ cụ thể sử dụng hàm imfilter: Giả sử ta có một ảnh f ở class double, kích
thước 512x512 >>w=ones(31);
cho ta mặt nạ lọc là ma trận vuông 31 31. Do đây là ma trận đối xứng nên toán tương quan và chập là như nhau. a b c d e f Hình 2.4
Hình a là ảnh ban đầu. Hình b là kết quả của quá trình lọc ảnh dùng padding là các mức xám giá trị 0(màu đen), ta thấy ảnh bị làm mờ đi ở cạnh giữa 2 vùng trắng và đen, cũng như giữa phần biên ảnh với vùng trắng. Điều này có thể giải thích như sau: Do mức xám tại một điểm là tổng của các tích mức xám các điểm vùng lân cận với hệ số của bộ lọc, ở đây các hệ số bộ lọc là 1, do đó mỗi điểm ảnh xem như là giá trị trung bình của các điểm ảnh xung quanh, dẫn đến kết quả như trên. Ta có thể loại bỏ phần mờ ở vùng biên bằng cách dùng thông số „replicate‟
hoặc „symmetric‟ như ở kết quả c và d. Với hình e, ta sử dụng thông số „circular‟. Do sự lập lại có tính chu kỳ làm cho vùng sáng và tối nằm cạnh nhau, dẫn đến kết quả là toàn bộ biên ảnh cũng như phần cạnh giữa 2 vùng sáng và tối bên trong bức ảnh bị mờ.
Nếu ta sử dụng ảnh ban đầu là class uint8 và sử dụng bộ lọc w như trên, ta nhận được kết quả là hình f với một phần dữ liệu ảnh gốc bị mất. Lý do là các giá trị lớn hơn 255 đều bị gán giá trị 255. Để giải quyết vấn đề đó, cửa sổ lọc cần được chuẩn hóa trước khi tiến hành lọc:
>>w=w/(sum(w(:)));
Ta có công thức tính mức xám của ảnh sau xử lý qua bộ lọc chuẩn hóa:
2.2.2.2 Biến đổi ảnh
a) Phép biến đổi mức xám
Trong phép biến đổi này, giá trị g(x,y) chỉ phụ thuộc vào giá trị của f(x,y), và T trở thành hàm biến đổi mức xám. Ta có biểu thức đơn giản sau:
Với r là mức xám ban đầu tại (x,y), s là mức xám sau biến đổi tại (x,y). Ví dụ: Xét hai phép biến đổi mức xám sau:
Hình 2.5
Với hình a, phép biến đổi cho ta ảnh sau xử lý có độ tương phản cao hơn so với ảnh ban đầu. Các giá tri mức xám r<m qua phép biến đổi được nén lại gần mức 0( tối hơn), tương tự với các giá trị r>m nhưng được nén lại gần mức 1( sáng hơn) làm ảnh sau xử lý có độ tương phản cao. Phép biến đổi ở hình b nhằm biến 1 ảnh grayscale thành 1 ảnh nhị phân. Ta xét mức ngưỡng m, với r<m được xét thành mức 0, và r>m xét thành mức 1.
b) Ảnh âm bản
Với 1 ảnh có các giá trị mức xám nằm trong khoảng [0,L-1], ta có: s=L-1-r
Hình 2.6
Hình trên là hình chụp một mô ngực, với ảnh bên trái là ảnh gốc và bên phải là ảnh âm bản. Ta có thể dễ dàng thấy được việc phân tích sẽ dễ dàng hơn với
ảnh âm bản.
c) Phép biến đổi log
Biểu thức:
s=c*log(1+r)
Các giá trị r mức thấp dải hẹp qua phép biến đổi sẽ tạo ra dải rộng hơn, trong khi đó các giá trị r mức cao sẽ nén lại thành 1 dải hẹp ở ngõ ra. Phép biến đổi này nhằm mục đích tăng chi tiết hóa ở vùng tối.
d) Biến đổi theo quy tắc lũy thừa
Biểu thức:
Hình 2.8
- Với y <1, phép biến đổi tương tự với hàm log, nhưng giá trị của có thể thay đổi được, trong khi hàm log là cố định. Với phép biến đổi này, các giá trị r mức thấp dải hẹp qua phép biến đổi sẽ tạo ra dải rộng hơn, trong khi đó các giá trị r mức cao sẽ nén lại thành 1 dải hẹp ở ngõ ra.
- Với y =1, phép biến đổi là một hàm tuyến tính giữa ngõ vào và ngõ ra. Đặc biệt khi c=1,ảnh ra và ảnh vào là giống nhau.
Hình 2.10
Ta nhận thấy y<1 làm tăng độ tương phản của hình ảnh.
Trong Matlab cũng có các hàm giúp biến đổi mức xám của ảnh grayscale. g=imadjust(f,[low_in high_in], [low_out
high_out],gamma])
[low_in, high_in], [low_out, high_out] nằm trong khoảng [0,1]. Các giá trị nhỏ hơn hoặc bằng low_in sẽ được gán bằng low_out và cũng tương tự với các giá trị
high_in và high_out.. Giá trị mặc định của gamma=1. Ví dụ: >>g=imadjust(f,[0.5 0.75],[0 1],2);
Ta cũng có thể dùng hàm imadjust để tạo ảnh âm bản: >>g=imadjust(f,[0 1],[1 0]);
2.2.3 Phân ngưỡng
Ảnh thu được từ camera đưa vào xử lý là ảnh màu RGB, vì vậy phải chuyển sang ảnh xám để tiến hành phân ngưỡng.
Ảnh RGB:
Ảnh xám:
Hinh 2.13
Ta thấy ảnh màu được hợp thành từ 3 ma trận hai chiều thể hiện cho thành phần màu của ảnh. Ảnh xám là ma trận hai chiều thể hiện mức xám, mỗi pixel có giá trị xám từ 0 đến 255.
Ta có công thức chuyển đổi ảnh từ màu sang xám:
Giatrixam = 0.2989 * R + 0.5870 * G + 0.1140 * B
R, G, B là giá trị 3 thành phần màu của ảnh màu. Các hệ số được chọn theo phần mền Matlab.
Trong Matlab cũng hỗ trợ hàm chuyển đổi rgb2gray chuyển từ ảnh màu sang ảnh xám.
Để phân biệt đối tượng với nên ta tiến hành phân ngưỡng ảnh. Là tạo ảnh chỉ còn hai mức từ 255 mức của ảnh xám. Mỗi pixel của ảnh được phân ngưỡng chỉ mang hai giá trị 1 hoặc 0, khi đó đối tượng và nên mang hai giá trị khác nhau.
Trong Matlab có hỗ trợ hàm chuyển sang ảnh nhị phân theo ngưỡng im2bw BW = im2bw(I, level)
level : ngưỡng thiết lập
2.2.4 Khử nhiễu và tách đối tượng
Ảnh sau khi được phân ngưỡng sẽ bao gồm nhiều đối tượng và nhiễu cùng một giá trị, còn nền mang một giá trị khác. Nhưng trong đó chỉ có một đối tượng ta quan tâm nên phải tiến hành khử nhiễu và tách bỏ những đối tượng khác.
Để thực hiện việc này ta sử dụng phương pháp làm đầy và bào mòn ảnh.
+ Làm đầy hay còn gọi là mở rộng ảnh:
Ta có hai ảnh nhị phân A, B với A là ảnh cần mở rộng, B là ma trận cấu trúc Việc mở rộng ảnh thể hiện qua hàm:
Mô tả dạng pixel:
Ví dụ thể hiện:
+ Bào mòn hay còn gọi là tỉa ảnh: Được thể hiện qua hàm:
Mô tả dạng pixel:
+ Kết hợp làm đầy và bào mòn
Làm đầy trước bào mòn sau thể hiện qua hàm:
Trong matlab có hàm thực hiện quá trình nay là STREL và IMCLOSE
STREL dung để tạo ra một ma trận cấu trúc B theo một cấu trúc hình dạng dụng như : đường thẳng , hình thoi , hình đĩa , đường thẳng điều hoà và hình quả bóng Chẳng hạn , đoạn mã sau tạo một phần tử cấu trúc phẳng có dạng hình thoi se = strel('diamond',3)
se =
Flat STREL object containing 25 neighbors.
Decomposition: 3 STREL objects containing a total of 13 neighbors Neighborhood: 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0
Hay dạng hình vuông có kích thước 3x3 . SE = strel('square',3)
SE =
Flat STREL object containing 3 neighbors. Neighborhood:
1 1 1 1 1 1 1 1 1
2.2.5 Xuất tín hiệu điều khiển robot
Thực hiện việc điều khiển robot sao cho đối tượng trong không gian ảnh luôn ở vị trí trung tâm của mặt phẳng ảnh.Với cách bố trí camera trong hệ robot – camera như hình:
Hình 2.15
Nếu chúng ta di chuyển đối tượng trong vùng nhìn thấy của camera), vi tri đối tượng và diện tích đối tượng trong khung ảnh sẽ thay đổi.
Tùy vào sự thay đổi này của đối tượng trong không gian của ảnh mà ta xuất tín hiệu điều khiển robot phù hợp.
Điều khiển robot sao cho robot bám theo đối tượng với khoảng cách giữa robot và đối tượng được không đổi, đối tượng trong khung ảnh luôn ở vị trí trung tâm không gian ảnh.
Khoảng cách này được tính toán bằng thực nghiệm thông qua diện tích của đối tượng trong ảnh.
2.2.5.1 Trên Matlab
Với cách ghép nối hệ robot – camera như đã nêu ở phần trên, áp dụng cách tính khoảng cách trong phần trên, ta có thể điều khiển robot bám theo đối tượng với khoảng cách thay đổi tùy vào giá trị đặt. Thể hiện theo lưu đồ sau:
Điều khiển robot được xác định theo sự sai lệch diện tích đối tượng so với diện tích thiết lập. Gọi :
- Stl : là diện tích thiết lập - S : diện tích đối tượng
- S2 : diện tích đối tượng bên nửa phải của ảnh
Hinh 2.16: lưu đồ điều khiển robot
Điều khiển Robot
S1S2 S1>S2 SStl S>Stl Truyền 49 Truyền 51 Truyền 52 Truyền 50 Truyền 0 S Đ Đ S Đ S S Đ
2.2.5.2 Dưới Vi điều khiển
+) Với giá trị nhận được từ máy tính truyền xuống
Vi điều khiển sẽ điều khiển robot hoạt động theo lưu đồ sau:
Hình 2.17: Lưu đồ giải thuật trên vi điều khiển
i=49 Rẽ phải i=51 Gán dữ liệu vào i Rẽ trái Đ S Đ S Nhận dữ liệu i=50 Lùi Tiến i=52 i=0 Dừng Đ S Đ S Đ S
+) Sử dụng phương pháp điều chỉnh độ rộng xung (PWM) để điều khiển tốc
độ động cơ điều khiển robot. Chọn phương pháp này vì chúng dễ thực hiện, mạch cấu tạo đơn giản.
. . hi lo avg V a V b V a b Hình 2.18
Khi tỷ lệ thời gian "on" trên thời gian "off" thay đổi sẽ làm thay đổi điện áp trung bình (VAVG). Tỷ lệ phần trăm thời gian "on" trong một chu kỳ chuyển mạch