Phần 4. Thay đổi kích thước ảnh với OpenCV

0
3715
Phần 4

Sau khi đã tìm hiểu những thao tác cơ bản về đọc và ghi ảnh hoặc video, bài viết này sẽ giới thiệu về cách thay đổi kích thước hình ảnh với OpenCV.

Khi thay đổi kích thước hình ảnh, cần lưu ý những điểm sau:

– Kích thước ban đầu của hình ảnh (tức là chiều rộng và chiều cao).

– Việc giảm kích thước của hình ảnh sẽ cần phải điều chỉnh giá trị pixel.

– Việc tăng kích thước của hình ảnh đòi hỏi phải tạo mới hình ảnh. Điều này có nghĩa là cần phải nội suy các pixel mới.

Có rất nhiều kỹ thuật nội suy khác nhau ra đời để thực hiện thao tác này. Trong OpenCV có hỗ trợ một số phương pháp và sự lựa chọn thường phụ thuộc vào ứng dụng cụ thể.

Nội dung bài viết gồm các nội dung chính sau:

1. Đọc hình ảnh sử dụng hàm imread()

2. Thay đổi kích thước hình ảnh với chiều rộng và chiều cao có thể tùy biến

3. Thay đổi kích thước hình ảnh với hệ số tỷ lệ

4. Thay đổi kích thước hình ảnh với các phương pháp nội suy khác nhau

Đầu tiên sẽ là code tham khảo việc thay đổi kích thước hình ảnh với chiều cao và chiều rộng tùy biến.

Python

# let's start with the Imports 
import cv2
import numpy as np

# Read the image using imread function
image = cv2.imread('image.jpg')
cv2.imshow('Original Image', image)

# let's downscale the image using new  width and height
down_width = 300
down_height = 200
down_points = (down_width, down_height)
resized_down = cv2.resize(image, down_points, interpolation= cv2.INTER_LINEAR)

# let's upscale the image using new  width and height
up_width = 600
up_height = 400
up_points = (up_width, up_height)
resized_up = cv2.resize(image, up_points, interpolation= cv2.INTER_LINEAR)

# Display images
cv2.imshow('Resized Down by defining height and width', resized_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining height and width', resized_up)
cv2.waitKey()

#press any key to close the windows
cv2.destroyAllWindows()

C++

// let's start with including libraries 
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;

int main()
{
	// Read the image using imread function
	Mat image = imread("image.jpg");
	imshow("Original Image", image);


	// let's downscale the image using new  width and height
	int down_width = 300;
	int down_height = 200;
	Mat resized_down;
	//resize down
	resize(image, resized_down, Size(down_width, down_height), INTER_LINEAR);
	// let's upscale the image using new  width and height
	int up_width = 600;
	int up_height = 400;
	Mat resized_up;
	//resize up
	resize(image, resized_up, Size(up_width, up_height), INTER_LINEAR);
	// Display Images and press any key to continue
	imshow("Resized Down by defining height and width", resized_down);
	waitKey();
	imshow("Resized Up image by defining height and width", resized_up);
	waitKey();


	destroyAllWindows();
	return 0;
}

1. Đọc hình ảnh

Phần này đã được giới thiệu ở bài viết trước. Trước hết cần khai báo các thư viện cần thiết:

Python

# Importing the libraries  
import cv2
import numpy as np

C++

#include<opencv2/opencv.hpp>
#include<iostream>
// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;

Tiếp theo sử dụng hàm imread() để đọc hình ảnh cần chỉnh sửa. Hình ảnh xe hơi dưới đây sẽ được sử dụng trong cả bài viết.

Ảnh gốc

Python

# Reading image
image= cv2.imread('image.jpg')

C++

// Reading image
   Mat image = imread("image.jpg");

Lưu ý rằng trong C ++, trước tiên cần một ma trận cho hình ảnh, sau đó sử dụng hàm imread () để đọc nó.

Trước khi bắt đầu thay đổi kích thước hình ảnh, cần biết kích thước ban đầu của nó. Để có được kích thước của một hình ảnh:

– Sử dụng phương thức hình dạng trong Python

– Hàng và cột trong C ++

Phương thức image.shape trong Python trả về ba giá trị: Chiều cao, chiều rộng và số kênh.

Trong C ++:

image.rows cung cấp thông tin chiều cao

image.columns cung cấp thông tin chiều rộng của hình ảnh

Cũng có thể thu được các kết quả trên bằng cách sử dụng hàm size ().

image.size ().width trả về chiều rộng

image.size ().height trả về chiều cao

Python

# Get original height and width
h,w,c = image.shape
print("Original Height and Width:", h,"x", w)

C++

// Get height and width
cout << "Original Height and Width :" << image.rows << "x" << image.cols << endl;

Một điều quan trọng cần lưu ý ở đây là OpenCV xuất ra hình ảnh ở định dạng chiều cao * chiều rộng * kênh, trong khi một số thư viện xử lý hình ảnh khác đưa ra ở dạng chiều rộng*chiều cao* kênh. Cần lưu ý sự khác nhau này để trích xuất được chính xác dữ liệu mong muốn. Ngoài ra có thể lợi dụng tính chất của NumPy để điều chỉnh vấn đề này.

Khi hình ảnh được đọc bằng OpenCV, chúng được biểu diễn dưới dạng mảng NumPy. Và nói chung khi đề cập đến kích thước của một mảng sẽ là dạng hàng * cột (trong đó các hàng biểu thị chiều cao và các cột là chiều rộng). Khi sử dụng OpenCV để lấy kích thước của ảnh, quy tắc mảng NumPy vẫn hoạt động. Và khi đó sẽ nhận được định dạng ảnh ở dạng chiều cao * chiều rộng *kênh.

Cú pháp hàm thay đổi kích thước: resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

Hàm resize() có 2 đối số đầu vào:

1. Đường dẫn tới ảnh gốc

2. Kích thước mong muốn của ảnh sau khi thay đổi

Cụ thể:

src: đường dẫn của hình ảnh đầu vào (ví dụ: ‘test_image.png’).

dsize: Là kích thước mong muốn của hình ảnh đầu ra, nó có thể là chiều cao và chiều rộng mới.

fx: Hệ số tỷ lệ theo trục hoành.

fy: Hệ số tỷ lệ theo trục tung.

interpolation: tùy chọn các phương pháp nội suy khác nhau để thay đổi kích thước hình ảnh.

2. Thay đổi kích thước ảnh bằng cách chỉ định chiều rộng và chiều cao

Bên dưới là code để thay đổi kích thước hình ảnh bằng cách chỉ định chiều rộng và chiều cao mới. Trong đó:

– Chiều rộng mong muốn là 300 và chiều cao mong muốn là 200

– Hai giá trị này được kết hợp trong một vectơ 2D, được yêu cầu bởi hàm resize()

– Phương pháp nội suy cũng được chỉ định cụ thể

Python

# Set rows and columns 
# lets downsize the image using new  width and height
down_width = 300
down_height = 200
down_points = (down_width, down_height)
resize_down = cv2.resize(image, down_points, interpolation= cv2.INTER_LINEAR)

C++

// Set rows and columns 
// lets downsize the image using new width and height
   int down_width = 300;
   int down_height = 200;
   Mat resize_down;

   // resize down
   resize(image, resize_down, Size(down_width, down_height), INTER_LINEAR);

Tiếp theo, tạo một biến khác để tăng kích thước của hình ảnh. Quy trình và các bước tương tự như giảm kích thước.

Python

# Set rows and columns
up_width = 600
up_height = 400
up_points = (up_width, up_height)
# resize the image
resized_up = cv2.resize(image, up_points, interpolation = cv2.INTER_LINEAR)

C++

// Set rows and columns
int up_width = 600;
int up_height = 400;
Mat resized_up;
//resize up
resize(image, resized_up, Size(up_width, up_height), INTER_LINEAR);

Sử dụng hàm imshow() từ OpenCV để kiểm tra kết quả

Python

# Display images
cv2.imshow('Resized Down by defining height and width', resized_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining height and width', resized_up)
cv2.waitKey()
cv2.destroyAllWindows()

C++

// Display Images and press any key to continue
imshow("Resized Down by defining height and width", resized_down);
waitKey();
imshow("Resized Up image by defining height and width", resized_up);
waitKey();
destroyAllWindows();
Bên trái là hình ảnh có kích thước bị thu nhỏ trong khi bên phải kích thước được tăng lên

Như vậy code ở trên đã hoạt động như mong đợi và kết quả thu được hình ảnh lớn hơn hoặc nhỏ hơn, theo các thông số chiều cao và chiều rộng mới mà đã được chỉ định.

Nhưng việc thay đổi kích thước bằng cách xác định một giá trị cụ thể cho chiều rộng và chiều cao làm cho hình ảnh kết quả bị méo. Có nghĩa là, tỷ lệ khung hình của hình ảnh không được giữ nguyên.

Để khắc phục điều này thì sẽ sử dụng hệ số tỷ lệ khi thay đổi kích thước.

3. Thay đổi kích thước hình ảnh với hệ số tỷ lệ

Trước khi sử dụng phương pháp này, chúng ta cần phải hiểu ý nghĩa của hệ số tỷ lệ trong kích thước hình ảnh. Hệ số tỷ lệ thường là một số chia hoặc nhân tỷ lệ với một số đại lượng, trong trường hợp hình ảnh là chiều rộng và chiều cao. Nó giúp giữ nguyên tỷ lệ khung hình và bảo toàn chất lượng hiển thị. Nhờ vậy, hình ảnh không bị biến dạng khi thay đổi kích thước.

Python

# Scaling Up the image 1.2 times by specifying both scaling factors
scale_up_x = 1.2
scale_up_y = 1.2
# Scaling Down the image 0.6 times specifying a single scale factor.
scale_down = 0.6

scaled_f_down = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_LINEAR)
scaled_f_up = cv2.resize(image, None, fx= scale_up_x, fy= scale_up_y, interpolation= cv2.INTER_LINEAR)

C++

// Scaling Up the image 1.2 times by specifying both scaling factors
double scale_up_x = 1.2;
double scale_up_y = 1.2;
// Scaling Down the image 0.6 times specifying a single scale factor.
double scale_down = 0.6;
Mat scaled_f_up, scaled_f_down;
//resize 
resize(image,scaled_f_down, Size(), scale_down, scale_down, INTER_LINEAR);
resize(image, scaled_f_up, Size(), scale_up_x, scale_up_y, INTER_LINEAR);

Trong đoạn code Python:

– Xác định các hệ số tỷ lệ mới dọc theo trục ngang và trục dọc.

– Việc xác định các hệ số tỷ lệ loại bỏ sự cần thiết phải có các điểm mới cho chiều rộng và chiều cao. Do đó, dsize được đặt là None.

Trong đoạn code C ++:

– Xác định các yếu tố tỷ lệ mới cũng như ma trận cho các hình ảnh mới.

– Vì không cần các điểm mới cho chiều rộng và chiều cao, nên Size() sẽ để trống và sử dụng hàm resize().

Sử dụng hàm imshow() để hiển thị hình ảnh cho dễ hình dung và hiểu rõ hơn.

Python

# Display images and press any key to check next image
cv2.imshow('Resized Down by defining scaling factor', scaled_f_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining scaling factor', scaled_f_up)
cv2.waitKey()

C++

// Display images and Press any key to continue check next image
imshow("Resized Down by defining scaling factor", scaled_f_down);
waitKey();
imshow("Resized Up by defining scaling factor", scaled_f_up);
waitKey();
Bên trái là phiên bản giảm tỷ lệ còn bên phải là tăng tỷ lệ

4. Thay đổi kích thước hình ảnh với các phương pháp nội suy khác nhau

Các phương pháp nội suy khác nhau được sử dụng cho các mục đích thay đổi kích thước khác nhau. Cụ thể như sau:

INTER_AREA: sử dụng quan hệ vùng pixel để lấy mẫu lại. Phương pháp phù hợp để giảm kích thước của hình ảnh (thu nhỏ).

INTER_CUBIC: sử dụng phép nội suy hai chiều để thay đổi kích thước hình ảnh. Quá trình thay đổi kích thước và nội suy các pixel mới, phương pháp này xem xét các vùng pixel 4 × 4 lân cận nhau của hình ảnh. Sau đó, nó lấy trung bình trọng số của 16 pixel để nội suy ra giá trị pixel mới.

INTER_LINEAR: Phương pháp khác phương pháp INTER_CUBIC ở chỗ nó xem xét các vùng pixel 2 × 2 lân cận để lấy giá trị trung bình có trọng số để nội suy ra giá trị pixel mới.

INTER_NEAREST: Phương pháp INTER_NEAREST sử dụng khái niệm “hàng xóm” gần nhất để nội suy. Đây là một trong những phương pháp đơn giản nhất, chỉ sử dụng một pixel lân cận từ hình ảnh để nội suy ra giá trị pixel mới.

Cụ thể từng phương pháp nội suy sẽ được đề cập trong các bài viết riêng khác. Bên dưới là code tham khảo cho việc sử dụng các phương pháp nội suy.

Python

# Scaling Down the image 0.6 times using different Interpolation Method
res_inter_nearest = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_NEAREST)
res_inter_linear = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_LINEAR)
res_inter_area = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_AREA)

C++

# Scaling Down the image 0.6 using different Interpolation Method
Mat res_inter_linear, res_inter_nearest, res_inter_area;
resize(image, res_inter_linear, Size(), scale_down, scale_down, INTER_LINEAR);
resize(image, res_inter_nearest, Size(), scale_down, scale_down, INTER_NEAREST);
resize(image, res_inter_area, Size(), scale_down, scale_down, INTER_AREA);

Sử dụng imshow() để quan sát kết quả

Python

# Concatenate images in horizontal axis for comparison
vertical= np.concatenate((res_inter_nearest, res_inter_linear, res_inter_area), axis = 0)
# Display the image Press any key to continue
cv2.imshow('Inter Nearest :: Inter Linear :: Inter Area', vertical)

C++

Mat a,b,c;
vconcat(res_inter_linear, res_inter_nearest, a);
vconcat(res_inter_area, res_inter_area, b);
vconcat(a, b, c);
// Display the image Press any key to continue
imshow("Inter Linear :: Inter Nearest :: Inter Area :: Inter Area", c);
Từ trái qua phải lần lượt là phương pháp nội suy INTER_LINEAR, INTER_NEAREST, và INTER_AREA

Ảnh GIF bên dưới cho thấy quá trình thực thi code hoàn chỉnh cho tất cả các thao tác thay đổi kích thước đã trình bày ở trên bao gồm: thay đổi kích thước theo chiều rộng và chiều cao của hình ảnh, hệ số tỷ lệ và các phương pháp nội suy khác nhau.

Ở bài viết tiếp theo, chúng ta sẽ cùng tìm hiểu một số thao tác cắt, xóa trong ảnh với OpenCV.

Biên dịch: Thảo Nguyễn

Để cập nhật tin tức công nghệ mới nhất và các sản phẩm của công ty AIoT JSC, vui lòng truy cập link: http://aiots.vn hoặc linhkienaiot.com

0 0 Phiếu bầu
Article Rating
Subscribe
Notify of
guest
0 Comments
Phản hồi nội tuyến
Xem tất cả các bình luận