Tìm hiểu về OpenCV
Bài đăng này đã không được cập nhật trong 2 năm
Hôm nay mình có xem 1 đoạn video ngắn rất thú vị về Deep Learning CycleGAN Đây là video giới thiệu về CycleGAN. CycleGAN là thuật toán sử dụng Deep Learning để chuyển đổi bề mặt 2 hình ảnh mà vẫn giữ nguyên backgroung của khung hinh, như trong video chuyển từ ảnh ngựa thường sang ngựa vằn, v.v... CycleGAN áp dụng cho cả hình ảnh và video Mình xem video mục đích là để tìm hiểu về Deep Learning nhưng sau khi xem xong thì lại tò mò về cách chuyển ảnh ngựa thường sang ngựa vằn hơn :v, vì vậy đã đi google, có rất nhiều kết quả. Đầu tiên thì mình thử sử dụng PIL, kết quả khá tốt tuy vẫn còn lỗi và code thì quá là dài, sau đó có tham khải imagemagick nhưng do thích viết python hơn với cả đọc document cũng bảo là thời gian chạy lâu nên bỏ qua. Cuối cùng thì mình tìm ra opencv (trước chỉ nghe tên mà không biết để làm gì) thì thấy quả là vi diệu, code ngắn, độ chính xác cao hơn, thời gian chạy cũng ngắn. Trong bài viết này mình chỉ giới thiệu về bleding image Tuy nhiên nếu bạn xem xong video mà hứng thú về deep learning thì có thể tham khảo trên github, tác giả đã public toàn bộ sourcode được viết bằng Torch https://junyanz.github.io/CycleGAN/.
Giới thiệu về Opencv
1. Opencv là gì
OpenCV (Open Computer Vision) là một thư viện mã nguồn mở hàng đầu cho xử lý về thị giác máy tính, machine learning, xử lý ảnh. OpenCV đươc viết bằng C/C++, vì vậy có tốc độ tính toán rất nhanh, có thể sử dụng với các ứng dụng liên quan đến thời gian thực. Opencv có các interface cho C/C++, Python Java vì vậy hỗ trợ được cho Window, Linux, MacOs lẫn Android, iOS OpenCV có cộng đồng hơn 47 nghìn người dùng và số lượng download vượt quá 6 triệu lần
2. Ứng dụng
Opencv có rất nhiều ứng dụng:
- Nhận dạng ảnh
- Xử lý hình ảnh
- Phục hồi hình ảnh/video
- Thực tế ảo
- Các ứng dụng khác
3. Cài đặt
Mình cài đặt opencv cho python 2.7 trên ubuntu
sudo apt-get install python-matplotlib
sudo apt-get install python-opencv
Pyramid
Pyramid, hoặc pyramid representation, là một dạng biểu diễn tín hiệu đa dạng được dùng trong computer vision, xử lý hình ảnh hoặc các xử lý tín hiệu. Trong đó, một tín hiệu hoặc một hình ảnh được lặp lại với các phương pháp smoothing và subsampling. Tên gọi pyramid biểu thị cho việc biểu diễn trong không gian và các phương pháp phân tích. Một image pyramid thực chất là một tập hợp các hình ảnh mà tất cả chúng đều phát sinh từ một hình ảnh ban đầu duy nhất, hình ảnh này được liên tục được lấy mẫu xuống cho tới khi đạt đến một điểm dừng mong muốn. Có hai loại image pỷamid ảnh phổ biến:
- Gaussian pyramid: Sử dụng để downsample hình ảnh tức là để giảm độ phân giải của hình ảnh
- Laplacian pyramid: Được sử dụng để tái tạo lại một hình ảnh được lấy mẫu từ một hình ảnh thấp hơn trong pyramid (có độ phân giải thấp hơn)
Gaussian pyramid
Gaussian pyramid là một tập các layer trong đó layer ở vị trí càng cao thì càng có kích thước nhỏ
Mỗi layer được đánh số từ dưới lên trên, do đó, layer(i + 1) (được biểu thị là G(i + 1) nhỏ hơn layer i (G(i))
- Gắn lại G(i) thành một Gaussian kernel:
- Loại bỏ tất cả các hàng và cột số chẵn
Bạn có thể dễ dàng nhận thấy rằng hình ảnh kết quả sẽ chỉ chính xác bằng một phần tư ảnh trước đó. Lặp đi lặp lại quá trình nhiều lần với hình ảnh đầu vào G(0) (hình ảnh ban đầu) ta sẽ có một tập layer image pyramid.
Quá trình trên đã làm giảm độ chính xác của ảnh, vậy để tăng kích thước thì sao? Đầu tiên, ta tăng ma trận hình ảnh lên gấp đôi bản gốc trong mỗi chiều, với các hàng và cột mới đầy những số không (0). Sau đó, thực hiện các bước lặp với cùng một kernel ở trên.
Laplacian pyramid
Laplacian pyramid được tạo ra Gaussian pyramid. Nếu bạn mở một ảnh Laplacian pyramid thì nó là một ảnh chỉ có các đường viền bao ngoài các vật thể, đã xóa hết các phần khác. Hầu hết các phần tử trong ma trận là zeros. Laplacian pyramid thường được sử dụng trong nén hình ảnh. Một level (mức độ) Laplacian pyrmaid được hình thành bởi sự khác biệt giữa level đó trong Gaussian pyramid và level trên nó (layer đã được mở rộng) trong Gaussian pyramid.
Demo
Mình sẽ demo bằng một chương trình đơn giản blend 2 ảnh,
Đầu vào, mình có 2 ảnh, một ảnh quả táo, 1 ảnh quả cam,
yêu cầu đầu ra là blend 2 ảnh này với nhau để thành một ảnh, một nửa là quả táo, 1 nửa là quả cam
- Đầu tiên, ta cần load ảnh, lấy được các thông số (blue, green, red), đối với bước này thì mình dùng 2 function
cv2.imread
vàcv2.
- Tiếp đến ta tính toán level của pyramid, ở đây mình đặt cho layer không lớn hơn 16x16
- Với mỗi thông số BGR, ta sẽ tạo ra một gaussian pyramid
def gauss_pyramid(image, levels):
output = []
output.append(image)
tmp = image
for i in range(0,levels):
tmp = ireduce(tmp)
output.append(tmp)
return output
ở đây trong funtion ireduce
mình đã tạo ra một kernel là một ma trận 5x5 làm giảm độ phân giải của ảnh đi 1/2
- Với mỗi thông số ta lại tiếp tục tạo ra một laplacian pyramid
def lapl_pyramid(gauss_pyr):
output = []
k = len(gauss_pyr)
for i in range(0,k-1):
gu = gauss_pyr[i]
egu = iexpand(gauss_pyr[i+1])
if egu.shape[0] > gu.shape[0]:
egu = np.delete(egu,(-1),axis=0)
if egu.shape[1] > gu.shape[1]:
egu = np.delete(egu,(-1),axis=1)
output.append(gu - egu)
output.append(gauss_pyr.pop())
return output
- Với mỗi thông số của 2 bức ảnh, ta blend các laplacian pyramid lại với nhau dựa trên một ảnh mask
def blend(lapl_pyr_white, lapl_pyr_black, gauss_pyr_mask):
blended_pyr = []
k= len(gauss_pyr_mask)
for i in range(0,k):
# print gauss_pyr_mask[i]
p1= gauss_pyr_mask[i]*lapl_pyr_white[i]
p2=(1 - gauss_pyr_mask[i])*lapl_pyr_black[i]
blended_pyr.append(p1 + p2)
return blended_pyr
- Cuối cùng ta cần tại tạo lại hình ảnh dự trên laplacian pyramid
Dưới đây là kết quả của mình, với đầu vào là 2 ảnh
code bạn có thể xem tại đây blending đoạn code này mình chạy trên ubuntu, python 2.7, ngoài opencv2 thì có import thêm scipy và numpy
Tham khảo
Để biết thêm về OpenCv bạn có thể tham khảo tại đây Homepage: http://opencv.org Docs: http://docs.opencv.org/master/ Q&A forum: http://answers.opencv.org Issue tracking: https://github.com/opencv/opencv/issues
All rights reserved