Xử lý ảnh - OpenCV resize, crop và padding hình ảnh (code Python và C++)
OpenCV - tut 2
Môi trường làm việc với OpenCV
- Linux (bài viết sử dụng Ubuntu 16.04)
- OpenCV (bài viết sử dụng OpenCV 3.4.1)
- Python (bài viết sử dụng Python 3.5.5)
- Ảnh mẫu để xử lý (bài viết sử dụng ảnh girl_xinh_2.jpg)
Quan trọng nhất vẫn là có ảnh mẫu để ta xử lý, hehe (keyword tìm kiếm cho ông nào cần ^^: girl xinh, cụ thể là tui lụm từ bài viết kenh14 :P):
girl_xinh_2.jpg
Bạn có thể download ảnh mẫu về.
File hình ảnh và source code python ở cùng thư mục:
- girl_xinh_2.jpg
- resize.py <– file python ở cùng thư mục với ảnh cho dễ thao tác
Resize ảnh với OpenCV - Python
Resize, hay gọi cách khác là scale ảnh, là việc ta chỉnh kích thước ảnh về kích thước mới (có thể giữ tỉ lệ ảnh ban đầu hoặc không).
resize.py: đọc file ảnh lên, resize ảnh (thay đổi kích thước), lưu xuống với OpenCV:
import cv2
IMG_PATH = 'girl_xinh_2.jpg'
# read image
img = cv2.imread(IMG_PATH)
print(IMG_PATH, img.shape)
new_width = 800
new_height = 400
img_resized = cv2.resize(src=img, dsize=(new_width, new_height))
reisze_img_name = 'girl_xinh_2_%dx%d.jpg' % (new_width, new_height)
cv2.imwrite(reisze_img_name, img_resized)
print(reisze_img_name, img_resized.shape)
fx = 0.5
fy = 1.0
img_resized = cv2.resize(src=img, dsize=None, fx=fx, fy=fy)
reisze_img_name = 'girl_xinh_2_fx=%.1f_fy=%.1f.jpg' % (fx, fy)
cv2.imwrite(reisze_img_name, img_resized)
print(reisze_img_name, img_resized.shape)
print('Done')
Thực thi lệnh trên terminal để đọc ảnh:
$ python resize.py
girl_xinh_2.jpg (720, 960, 3)
girl_xinh_2_800x400.jpg (400, 800, 3)
girl_xinh_2_fx=0.5_fy=1.0.jpg (720, 480, 3)
Done
Script ghi ra 2 ảnh mới:
- girl_xinh_2_800x400.jpg: giờ thì girl xinh của chúng ta đã bị kéo mặt mập ra rồi, heeh.
- girl_xinh_2_fx=0.5_fy=1.0.jpg
Giải thích về các tham số resize biến đổi kích thước ảnh OpenCV Python:
- Lệnh chỉnh kích thước: cv2.resize()
- dsize: kích thước mới (width, height). Tuy tổ chức dữ liệu là Height Width Channel nhưng tham số truyền vào là tuple lại sắp xếp Width trước rồi Height sau. Các bạn chú ý điểm này.
- fx, fy: dùng để biến đổi theo tỉ lệ ảnh thay vì kích thước tuyệt đối.
Các bạn có thể nghịch với đoạn code bằng cách chỉnh các tham số ^^.
Crop ảnh với OpenCV - Python
crop.py: đọc file ảnh lên, crop vùng ảnh theo trục y (50:400), theo trục x (240:720), lưu xuống với OpenCV:
import cv2
IMG_PATH = 'girl_xinh_2.jpg'
# read image
img = cv2.imread(IMG_PATH)
print(IMG_PATH, img.shape)
img_crop = img[50:400, 240:720, :]
crop_name = 'girl_xinh_2_crop.jpg'
print(crop_name, img_crop.shape)
cv2.imwrite(crop_name, img_crop)
print('Done')
Từ giờ về sau mình sẽ không nhắc đến câu lệnh thực thi code python OpenCV nữa, cú pháp mặc định như mọi lần nhe $ python tên_file.py
:
$ python crop.py
girl_xinh_2.jpg (720, 960, 3)
girl_xinh_2_crop.jpg (350, 480, 3)
Done
Sau khi cắt ảnh ra, ta chỉ còn mặt của cô gái. Mà không sao, em ấy vẫn xinh, kaka. :D.
girl_xinh_2_crop.jpg
Padding ảnh với OpenCV - Python
Padding ảnh là gì?
Padding ảnh là việc mà mình thêm các pixel vào các cạnh của ảnh để mở rộng ảnh ra.
Padding ảnh:
- Thông thường giá trị pixel padding thêm sẽ là zero. Tức có màu đen.
- Padding sẽ cho hiệu ứng zoom out. Tức nội dung ảnh sẽ nhỏ đi so với toàn ảnh.
- Bạn có thể tạo hiệu ứng grid bằng cách:
- Dùng OpenCV padding 1 ảnh to ra 2 lần về bên phải và xuống dưới.
- Sau đó đọc nội dung 3 ảnh khác bằng OpenCV rồi cắt dán các pixel vào 3 vùng trống vừa mở rộng ra bằng padding.
- Kết quả cuối cùng cho ảnh grid 2x2.
Nào, ta cùng padding ảnh thôi!
padding.py: padding ảnh thành kích thước 1000x1000
import cv2
import numpy as np
IMG_PATH = 'girl_xinh_2.jpg'
# read image
img = cv2.imread(IMG_PATH)
print(IMG_PATH, img.shape) # (720, 960, 3)
img_pad = np.zeros([1000, 1000, 3])
img_pad += 100 # grey color BGR: [100, 100, 100] <=> hex: #646464
img_pad[140:860, 20:980,:] = img
cv2.imwrite('girl_xinh_2_pad.jpg', img_pad)
print('girl_xinh_2_pad.jpg:', img_pad.shape)
print('Done')
Resize ảnh với OpenCV - C++
resize.cpp
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat)
// using namespace cv;
int main() {
cv::Mat img = cv::imread("girl_xinh_2.jpg", cv::IMREAD_COLOR); // (720, 960, 3)
cv::Mat img_resize;
cv::resize(img, img_resize, cv::Size(800,400));
cv::imwrite("girl_xinh_800x400.jpg", img_resize);
}
Crop ảnh với OpenCV - C++
crop.cpp
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat)
// using namespace cv;
int main() {
cv::Mat img = cv::imread("girl_xinh_2.jpg", cv::IMREAD_COLOR); // (720, 960, 3)
int startX=240, startY=50, width=480, height=350;
cv::Mat ROI(img, cv::Rect(startX, startY, width, height));
cv::Mat croppedImage;
// Copy the data into new matrix
ROI.copyTo(croppedImage);
cv::imwrite("girl_xinh_2_crop.jpg", croppedImage);
}
Padding ảnh với OpenCV - C++
padding.cpp
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat)
// using namespace cv;
int main() {
cv::Mat img = cv::imread("girl_xinh_2.jpg", cv::IMREAD_COLOR); // (720, 960, 3)
int new_height = 1000;
int new_width = 1000;
cv::Mat img_pad(new_height, new_width, img.type());
img_pad.setTo(100);
int x = 20;
int y = 140;
int width = 980 - x;
int height = 860 - y;
img.copyTo(img_pad(cv::Rect(x, y, width, height)));
cv::imwrite("girl_xinh_2_pad.jpg", img_pad);
}
Cảm ơn bạn đã theo dõi bài viết. Hãy kết nối với tớ nhé!
- Minh: https://www.facebook.com/minhng.info
- Khám phá xử lý ảnh - GVGroup: https://www.facebook.com/groups/ip.gvgroup
Khám phá xử lý ảnh - GVGroup
Danh sách bài viết series OpenCV:
- Hashtag #OpenCV
- Tut 1: Xử lý ảnh - OpenCV đọc ghi hình ảnh (code Python và C++)
- Tut 1.1: Xử lý ảnh - Cấu trúc dữ liệu ảnh trong OpenCV. Pixel là gì?
- Tut 1.2: Xử lý ảnh - Chuyển đổi ảnh OpenCV sang Pillow và ngược lại
- Tut 2: Xử lý ảnh - OpenCV resize, crop và padding hình ảnh (code Python và C++)
- Tut 3: Xử lý ảnh - OpenCV biến đổi mức sáng hình ảnh (code Python)
- Tut 4: Xử lý ảnh - OpenCV vùng quan tâm (ROI) là gì? (code Python)
- Tut 4.1: Xử lý ảnh - OpenCV: vẽ văn bản, đường thẳng, mũi tên, hình chữ nhật, hình tròn, ellipse, đa giác
- Tut 4.2: Xử lý ảnh - Pha trộn ảnh trong OpenCV (blending)
- Tut 5: Xử lý ảnh - OpenCV ảnh nhị phân
- Tut 6: Xử lý ảnh - OpenCV cân bằng sáng (histogram equalization)
- Tut 7: Xử lý ảnh - OpenCV kỹ thuật cửa sổ trượt (sliding window)
- Tut 8: Xử lý ảnh - Convolution là gì?
- Tut 9: Xử lý ảnh - Làm mờ ảnh (blur)
- Tut 10: Xử lý ảnh - Gradient của ảnh là gì?
- Tut 11: Xử lý ảnh - Phát hiện cạnh Canny (Canny Edge Detection)
- Tut 12: Xử lý ảnh - Phát hiện đường thẳng bằng Hough Transform (Hough Line)
- Tut 13: Xử lý ảnh - Hiện thực phát hiện đoạn thẳng dùng Hough Transform (Hough Line)
- Tut 14: Xử lý ảnh - Giải thuật phân vùng Region Growing trên ảnh màu
- Tut 15: Xử lý ảnh - Giải thuật Background Subtraction trên ảnh màu
- Tut 16: Xử lý ảnh - Frame Subtraction để phát hiện chuyển động trong video
- Tut 17: Xử lý ảnh - HOG - Histograms of Oriented Gradients
- Tut 18: Xử lý ảnh - HOG - Huấn luyện mô hình phân loại người
- Tut 19: Xử lý ảnh - HOG - Phát hiện người
- Tut 20: Xử lý ảnh - Tổng hợp kinh nghiệm xử lý ảnh (End)
- Tut 21: Xử lý ảnh - Hiện thực trích đặc trưng Local Binary Patterns (LBP)
- Tut 22: Xử lý ảnh - Trích đặc trưng Gabor filters