Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 16

PHẦN 1.

ĐẶT VẤN ĐỀ
Ứng dụng công nghệ xử lý ảnh để phân loại sản phẩm theo hình dạng có những chức
năng như sau:

- Chức năng nhận diện hình dạng sản phẩm cơ bản như hình tròn, hình vuông, hình chữ
nhật, hình tam giác
- Lưu được thông tin vào cơ sở dữ liệu

PHẦN 2. QUY TRÌNH THỰC HIỆN


Để tiến hành thực hiện được chương trình trên cần trải qua các bước sau:

Hình 1. Quy trình thực hiện


2.1. LỰA CHỌN NGÔN NGỮ LẬP TRÌNH
Để thực hiện giải quyết bàn toán trên lựa chọn ngôn ngữ C++
C++ là ngôn ngữ lập trình được phát triển từ ngôn ngữ C, với mục tiêu kết hợp
với hiệu suất cao và tính linh hoạt. Được tạo ra vào những năm 1979, nó được sử
dụng rộng rãi trong linh vực xử lý ảnh. OpenCV, hay Open Source Computer Vision
Library, là một thư viện mã nguồn mở chuyên dụng cho xử lý ảnh và thị giác máy
tính. Được phát triển bởi Intel vào năm 1999, nó là thư viện phổ biến được sử dụng để
xử lý ảnh bằng C++.
Hình 2. Ngôn ngữ lập trình C++
2.2. LỰA CHỌN MÔI TRƯỜNG LẬP TRÌNH
2.2.1. Môi trường lập trình
Sử dụng Visual Studio Code để làm môi trường lập trình
Visual Studio Code là một phần mềm lập trình C/C++ khá là tuyệt vời. Visual Studio
Code là mã nguồn có một cộng đồng hỗ trợ rộng lớn. Sử dụng IntelliSense giúp bạn giải
quyết tất cả các vấn đề khó. Với các lệnh Git được tích hợp sẵn, debug code chưa bao giờ dễ
dàng hơn với Visual Studio Code và còn nhiều tính năng khác khiến việc lập trình của bạn trở
nên thuận tiện hơn rất nhiều.

Hình 3. Visual Studio Code


2.2.2. Môi trường lập trình cơ sở dữ liệu
Sử dụng MySQL Workbench để làm môi trường lập trình cơ sở dữ liệu

2
MySQL Workbench là một công cụ truy cập cơ sở dữ liệu được mô hình hóa và thiết
kế trực quan sử dụng cho cơ sở dữ liệu quan hệ MySQL server. MySQL Workbench giúp tạo
ra các mô hình dữ liệu vật lý mới và hỗ trợ sửa đổi các cơ sở dữ liệu MySQL hiện có với các
kỹ thuật đảo ngược / chuyển tiếp, các chức năng quản lý tùy chọn.

Hình 4. MySQL Workbench


2.3. CÁC THUẬT TOÁN NHẬN DIỆN HÌNH DẠNG ĐỐI TƯỢNG
Dưới đây là một số thuật toán được sử dụng để nhận biết hình dạng đối tượng:
- Thuật toán HoughCircles trong xử lý ảnh được sử dụng để phát hiện vòng tròn trong
ảnh. Nó chuyển đổi mỗi điểm trên vòng tròn thành một điểm trong không gian tham số
và sau đó lọc kết quả để xác định vị trí và kích thước của các vòng tròn. Đây là một
phương pháp phổ biến trong các ứng dụng như nhận diện vật thể và xử lý hình ảnh
công nghiệp.
- Thuật toán Contours trong xử lý ảnh được sử dụng để phát hiện và xác định các đường
viền của các đối tượng trong hình ảnh. Thuật toán này giúp đơn giản hóa việc nhận
diện hình dạng và biên của các vật thể, thông thường được sử dụng trong các ứng
dụng như nhận diện đối tượng, theo dõi chuyển động, và xử lý hình ảnh y tế.

2.4. CÁC THƯ VIỆN CẦN CÀI ĐẶT


- OpenCV 2.4.13
- Mysql connector c++

PHẦN 3. THUẬT TOÁN


3.1. LƯU ĐỒ THUẬT TOÁN TỔNG QUÁT

3
3.1.1. Nếu sử dụng hình ảnh

Kết nố i cơ sở Khởi tạo biến


Bắt đầu dữ liệu hình ảnh

Ngắt kết nối Thuật toán Thuật toán


cơ sở dữ liệu Contours HoughCircles

Kết thúc

Hình 5. Sơ đồ thuật toán tổng quát sử dụng hình ảnh 3.1.1.


Nếu sử dụng camera

Kết nố i cơ sở Khởi tạo camera


Bắt đ ầu
dữ liệu

Ngắt k ết nối
cơ sở dữ liệu, Kết thúc
camera

Kiểm tra điều


kiện dừng lại S

Thuật toán Thuật toán Khởi tạo biến hình ảnh


Contours HoughCircles nhận hình ảnh từ
cammera

Hình 6. Sơ đồ thuật toán tổng quát sử dụng camera


3.2. LƯU ĐỒ THUẬT TOÁN HOUGHCIRCLES

4
Bắt đầu Tạo ảnh xám Tạo bộ nhỡ và làm
rỗng bộ nhớ

Lọc điều kiện, vẽ viền đường tròn ra màn hình, Phát hiện hình tròn
lưu thông tin vào cơ sở dữ liệu

Giải phóng bộ nhớ và kết


thúc

Hình 7. Sơ đồ thuật toán HoughCircles

3.3. LƯU ĐỒ THUẬT TOÁN CONTOURS

Bắt đ ầu Chuyển sang ảnh xám Phát hiện biên của


và giảm nhiễu ảnh xám

Lọc điều kiện xác định hình dạng, vẽ cạnh ra Tìm số cạnh của
màn hình, lưu thông tin vào cơ s ở dữ liệu hình

Giải phóng bộ nhớ và kết


thúc

Hình 8. Sơ đồ thuật toán Contours

PHẦN 4. CHƯƠNG TRÌNH


4.1. CÀI ĐẶT THƯ VIỆN
4.1.1. Cài đặt thư viện OpenCV 2.4.13
- Bước 1: Ấn Project > Property > C/C++ > General > Additional include directories >
Edit > copy đường dẫn …\opencv\build\include

5
Hình 9. Cửa sổ Property
- Bước 2: Ấn Linker > Input > Additional Dependencies > Edit > copy đường dẫn…\
opencv\build\x64\vc12\lib\*.lib

Hình 10. Cửa sổ Property


- Bước 3: Vào đường dẫn …\opencv\build\x64\vc12\bin copy toàn bộ file .dll

6
Hình 11. Thư mục file .dll
- Bước 4: vào file chứa project đã tạo paste toàn bộ file .dll vừa copy ở trên vào vị trí
như đường dẫn …\Project1\x64\Debug

Hình 11. Thư mục debug


4.1.2. Cài đặt thư viện MySQL Connecter/C++ Cài
đặt tương tự thư viện OpenCV 2.4.13.

7
4.2. CHƯƠNG TRÌNH

```C++

#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>

#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/statement.h>
#include <cppconn/exception.h>

using namespace std;

// kết nối mysql


sql::mysql::MySQL_Driver* driver; sql::Connection*
con;

void connectToMySQL() {
try {
driver = sql::mysql::get_mysql_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root","30102003");
con->setSchema("btlxla"); if (con){
cout << "Connected to MySQL successfully!" << endl;
} Else { cout << "Failed to connect to
MySQL." << endl;
}
}
catch (sql::SQLException& e) {
cout << "SQLException: " << e.what() << endl;
cout << "SQLState: " << e.getSQLState() << endl;
cout << "ErrorCode: " << e.getErrorCode() << endl;
}
}
void insertDataIntoTable(sql::Connection* con, const string&
hinhdang, const string& thongtin) { try {
sql::Statement* stmt = con->createStatement();
string query = "INSERT INTO hinh (hinh_dang, thong_tin) "
"VALUES ('" + hinhdang + "', '" + thongtin + "')"; stmt-
>executeUpdate(query); cout << "du lieu cap nhap thanh
cong" << endl;

delete stmt;
}
catch (sql::SQLException& e) {
cout << "Lỗi SQL: " << e.what() << endl;
} }
void disconnectFromMySQL() {
if (con) { delete
con;
cout << "Disconnected from MySQL server." << endl;
}
}

8
void Circles(IplImage* frame) {
IplImage* gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
cvCvtColor(frame, gray, CV_BGR2GRAY);
cvSmooth(gray, gray, CV_GAUSSIAN, 9, 9, 2, 2);

CvMemStorage* storage = cvCreateMemStorage(0);


cvClearMemStorage(storage);

// Detect Circles
//CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1,
gray->height / 8, 100, 30, 10, 90);
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1,
gray->height / 8, 100, 30, 70, 90);// neu dung cammera
// Draw Circles
for (int i = 0; i < circles->total; i++) {
float* p = (float*)cvGetSeqElem(circles, i);
CvPoint center = cvPoint(cvRound(p[0]), cvRound(p[1]));
int radius = cvRound(p[2]);

float ratio = (4 * CV_PI * pow(radius, 2)) / (CV_PI * pow(radius,


2));

if (ratio > 1.1 && ratio < 50) {


cvCircle(frame, center, 3, CV_RGB(0, 255, 0), -1, 8, 0);
cvCircle(frame, center, radius, CV_RGB(0, 0, 255), 3, 8, 0);
cout << "Hinh tron tam (" << center.x << ", " << center.y <<
") ban kinh " << radius << endl;
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8);
cvPutText(frame, "Hinh tron", cvPoint(center.x + radius - 10, center.y +
radius - 10), &font, CV_RGB(0, 69, 255));
string thongtin = "tam_(" + to_string(center.x) + "," +
to_string(center.y) + ")_ban_kinh_" + to_string(radius);
insertDataIntoTable(con, "hinh_tron",thongtin); } }
void detectShapes(IplImage* img) {
// Chuyển ảnh sang ảnh xám
IplImage* imgGray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
cvCvtColor(img, imgGray, CV_BGR2GRAY);
// Làm mờ ảnh để làm giảm nhiễu
cvSmooth(imgGray, imgGray, CV_GAUSSIAN, 5, 5);

// Phát hiện biên bằng cách sử dụng Canny


IplImage* imgCanny = cvCreateImage(cvGetSize(imgGray), IPL_DEPTH_8U,
1); cvCanny(imgGray, imgCanny, 50, 150,
3);
// Tìm contours trong ảnh
CvSeq* contours;
CvMemStorage* storage = cvCreateMemStorage(0);
cvFindContours(imgCanny, storage, &contours, sizeof(CvContour),
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
// Duyệt qua tất cả contours và xác định loại hình
for (CvSeq* contour = contours; contour != 0; contour = contour>h_next)
{

// Xấp xỉ contour bằng đa giác


CvSeq* approx = cvApproxPoly(contour, sizeof(CvContour), storage,
CV_POLY_APPROX_DP, 0.02 * cvArcLength(contour), 0);

9
// Lọc các đỉnh theo số đỉnh và diện tích
double area = fabs(cvContourArea(approx, CV_WHOLE_SEQ));
CvRect rect = cvBoundingRect(contour);
if (approx->total == 3 && area > 500)
{ // Vẽ đường contour lên ảnh gốc
cvDrawContours(img, approx, CV_RGB(255, 0, 0), CV_RGB(255, 0,
0), 0, 2);
cout << "Hinh tam giac tai toa do (" << rect.x << " " <<
rect.y << ")" << endl; CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8);
cvPutText(img, "Tam giac", cvPoint(rect.x, rect.y - 1), &font, CV_RGB(0,
69, 255));
string thongtin = "vi_tri_(" + to_string(rect.x) + "," +
to_string(rect.y) + ")";
insertDataIntoTable(con, "hinh_tam_giac", thongtin);
}
else if (approx->total == 4 && area > 1000) {
// Kiểm tra xem có phải là hình vuông hay hình chữ nhật
double ratio = (double)rect.width / (double)rect.height; if
(ratio > 0.8 && ratio < 1.2) {
// Vẽ đường contour lên ảnh gốc
cvDrawContours(img, approx, CV_RGB(0, 255, 0), CV_RGB(0,
255, 0), 0, 2);
cout << "Hinh vuong tai toa do (" << rect.x << " " <<
rect.y << ")" << " voi chieu rong " << rect.width << " va chieu cao " <<
rect.height << endl;
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1,
8); cvPutText(img, "Hinh vuong", cvPoint(rect.x, rect.y -
1),
&font, CV_RGB(0, 69, 255));
string thongtin = "vi_tri_(" + to_string(rect.x) + "," +
to_string(rect.y) + ")_rong_"+ to_string(rect.width) + "_cao_" +
to_string(rect.height); insertDataIntoTable(con,
"hinh_vuong", thongtin);
}
else {
// Vẽ đường contour lên ảnh gốc
cvDrawContours(img, approx, CV_RGB(0, 0, 255), CV_RGB(0,
0, 255), 0, 2);
cout << "Hinh chu nhat tai toa do (" << rect.x << " " <<
rect.y << ")" << " voi chieu rong " << rect.width << " va chieu cao " <<
rect.height << endl;
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1,
8); cvPutText(img, "Hinh chu nhat", cvPoint(rect.x,
rect.y -
1), &font, CV_RGB(0, 69, 255));
string thongtin = "vi_tri_(" + to_string(rect.x) + "," +
to_string(rect.y) + ")_rong_" + to_string(rect.width) + "_cao_" +
to_string(rect.height); insertDataIntoTable(con,
"hinh_chu_nhat", thongtin);
}
}
}
cvReleaseImage(&imgGray);
cvReleaseImage(&imgCanny);
}

10
int main() {
// Thay đổi đoạn mã để đọc ảnh từ tệp tin
connectToMySQL();
const char* filename = "C:\\Users\\mayti\\Downloads\\hinh.png"; //
Đặt đường dẫn tới ảnh của bạn
IplImage* frame = cvLoadImage(filename);

if (!frame) {
cerr << "Cannot open image file!" << endl;
return -1;
}
cvNamedWindow("Product Classification", CV_WINDOW_AUTOSIZE);
// Gọi các hàm xử lý trên ảnh
Circles(frame); detectShapes(frame);

cvShowImage("Product Classification", frame);


cvWaitKey(0);

cvReleaseImage(&frame);
cvDestroyAllWindows(); disconnectFromMySQL();

return 0;

11
// nếu sử dụng camera thì dùng hàm main này
/* int
main() {
connectToMySQL();
CvCapture* capture = cvCaptureFromCAM(0);
if (!capture) {
cerr << "Cannot open camera!" << endl;
return -1;
}
cvNamedWindow("Product Classification", CV_WINDOW_AUTOSIZE);
while (true) {
cvWaitKey(5000);
IplImage* frame = cvQueryFrame(capture);
if (!frame) {
cerr << "Cannot read frame from camera!" << endl;
break;
}

Circles(frame);
detectShapes(frame);

cvShowImage("Product Classification", frame);

char key = cvWaitKey(1);


if (key == 'q')
{ break;
}
}
cvReleaseCapture(&capture);
cvDestroyAllWindows();
disconnectFromMySQL();

return 0;
}
*/

PHẦN 5. KẾT LUẬN


5.1. KẾT QUẢ ĐẠT ĐƯỢC
5.1.1. Kết quả nếu sử dụng hình ảnh

12
Hình 12. Kết quả nếu sử dụng hình ảnh
5.1.2. Kết quả nếu sử dụng camera

Hình 13. Kết quả nếu sử dụng camera nhận biết hình tròn

13
Hình 14. Kết quả nếu sử dụng camera nhận biết hình chữ nhật

Hình 15. Kết quả nếu sử dụng camera nhận biết hình vuông

14
Hình 16. Kết quả nếu sử dụng camera nhận biết hình tam giác

5.1.3. thông tin lưu trên cơ sở dữ liệu

Hình 17. Kết quả hiển thị trên cơ sở dữ liệu

15
5.2. VẤN ĐỀ CẦN GIẢI QUYẾT
- Chưa có khả năng nhận diện hình khó như hình thoi, hình bình hành….
- Chưa tạo được giao diện than thiên với người dùng.
- Khả năng chính xác khi sử dụng camera không phải là tuyệt đối co thể bắt nhầm vật ta
không mong muốn.
- Các thuật toán sử dụng có những sai số nhất định so với thực tế.
- Khi sử dụng hình ảnh một số hình ảnh quá bé sẽ khó xác định.

16

You might also like