b Tìm các hình tròn trong hình có bán kính r=2 và 3 qua ít nhất 3 điểm bằng giải thuật houghcircle... Tương tự như cách tính trên, ta tổng hợp được tất cả bao gồm các điểm trên các toạ đ
Trang 1ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC BÁCH KHOA
……….oOo………
BÀI TẬP LỚN SỐ 2 – Nhóm 1
1 2010003 Tống Phước Thanh An
4 2014240 Nguyễn Đắc Đạo Quang
5 2013798 Trịnh Vũ Quốc Minh
TP HỒ CHÍ MINH - NĂM 2022
Trang 9Tìm các đường thẳng đi qua ít nhất 5 điểm
Đầu tiên ta tách hình 1 ra bằng hàm connectedComponents
image1.at<uchar>(Point(i, j)) = 255;
} }
}
Tất cả các đường thẳng không tính các đoạn Gap đều đi qua 6 điểm, như vậy chỉ cần tìm hết các đường thẳng, sử dụng hàm HoughLine để tìm lần lượt các đường nằm ngang và các đường thẳng đứng
vector <Vec2f> vertical_lines;
vector <Vec2f> horizon_lines;
HoughLines(image1,horizon_lines, 1, CV_PI, 5, 0, 0,-CV_PI/2, 2*CV_PI); //Tim cac duong nam ngang
HoughLines(image1, vertical_lines, 1, CV_PI / 2, 5, 0, 0, -CV_PI, CV_PI / 2); //Tim cac duong thang dung
Kết quả tìm các đường thẳng và phương trình đường thẳng
Hình 1.1 Đường thẳng đứng
Trang 11bitwise_and(drawing, drawing2, point);
vector <Point> intersection;
for (int i = 0; i < drawing.cols; i++)
{
for (int j = 0; j < drawing.rows; j++) {
if (point.at<uchar>(Point(i, j)) == 255) {
intersection.push_back(Point(i, j));
} }
}
cout << "Toa do giao diem cac duong thang tim duoc: " << endl;
Hình 1.4 Kết quả giao điểm tìm được
Nhận xét: Kết quả thu được hoàn toàn phù hợp với phần tính toán lý thuyết
Trang 12Mat scr = Mat(17, 18, CV_32F, data);
Mat image1 = Mat::zeros(17, 18, CV_8U);
Mat drawing = Mat::zeros(17, 18, CV_8U);
Mat drawing2 = Mat::zeros(17, 18, CV_8U);
Mat output = Mat::zeros(17, 18, CV_8U);
Mat point = Mat::zeros(17, 18, CV_8U);
image1.at<uchar>(Point(i, j)) = 255;
} }
}
cout << image1 << endl;
vector <Vec2f> vertical_lines;
vector <Vec2f> horizon_lines;
HoughLines(image1,horizon_lines, 1, CV_PI, 5, 0, 0,-CV_PI/2, 2*CV_PI); //Tim cac duong nam ngang
HoughLines(image1, vertical_lines, 1, CV_PI / 2, 5, 0, 0, -CV_PI, CV_PI / 2); //Tim cac duong thang dung
//Kết quả các đường thẳng
cout << "Ket qua thu duoc cac duong thang dung: " << endl;
for (int i = 0; i < vertical_lines.size(); i++)
Trang 13{
double rho = vertical_lines[ ][0 , theta = vertical_lines[ ][1 ; double a = cos(theta), b = sin(theta);
cout << "[rho theta] = " << vertical_lines[ ] << endl;
cout << "x = " << rho/a << endl;
cout << drawing << endl;
cout << "Ket qua thu duoc cac duong nam ngang: " << endl;
for (int i = 0; i < horizon_lines.size(); i++)
{
double rho = horizon_lines[ ][0 , theta = horizon_lines[ ][1 ; double a = cos(theta), b = sin(theta);
cout << "[rho theta] = " << horizon_lines[ ] << endl;
cout << "y = " << rho / b << endl;
cout << drawing2 << endl;
bitwise_or(drawing, drawing2, output);
cout << "Cac duong thang tim duoc: " << endl << output << endl;
bitwise_and(drawing, drawing2, point);
vector <Point> intersection;
for (int i = 0; i < drawing.cols; i++)
{
for (int j = 0; j < drawing.rows; j++) {
if (point.at<uchar>(Point(i, j)) == 255) {
intersection.push_back(Point(i, j));
} }
}
cout << "Toa do giao diem cac duong thang tim duoc: " << endl;
for (int i = 0; i < intersection.size(); i++)
Trang 14b) Tìm các hình tròn trong hình có bán kính r=2 và 3 qua ít nhất 3 điểm bằng giải thuật houghcircle Lập trình sử dụng hàm opencv tìm các đường tròn này
x
y 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
0 1 1
1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1 1 1
4 1 1 1 1 1 1
5 1 1 1 1 1 1 1 1 1 1 1
6 1 1 1 1 1 1 1 1
7 1 1 1
8 1 1 1 1 1
9 1 1 1 1 1 1 1 1
10 1 1 1 1 1 1 1
11 1 1 1 1 1 1 1
12 1 1 1 1 1 1 1
13 1 1 1 1 1 1 1
14 1 1 1 1 1 1 1 1 1
15 1 1 1 1 1 1
16 1
Tính tay
Toạ độ (xc,yc) được tính theo công thức:
xc=xi-rcos θ;
yc=yi-rsin θ
Xét bán kính r=2
Đường tròn đi qua 3 điểm:
(𝑥𝑖, 𝑦𝑖) 𝜃
𝑟 = 2
xuất hiện
(14,1)
Trang 17Đối với đường tròn có bán kính r=2: tồn tại đường tròn có tâm là (12,12) – đi qua
4 điểm có tọa độ (𝑥𝑖, 𝑦𝑖) lần lượt là (12,10); (10,12); (14,12); (12,14)
Trang 20Đối với đường tròn có bán kính r=3: tồn tại đường tròn có tâm là (10,11) – đi qua
4 điểm có tọa độ (𝑥𝑖, 𝑦𝑖) lần lượt là (10,8); (7,11); (13,11); (10,14)
Trang 21Tương tự như cách tính trên, ta tổng hợp được tất cả (bao gồm các điểm trên) các toạ độ tâm có r=2, r=3 như sau:
Trang 22threshold(src, src, 0, 255, THRESH_BINARY);
cout << "input image: " << endl << src << endl;
Trang 23Kết quả sau khi phân ngưỡng:
- Sử dụng hàm Hough Circle với để lọc các hình tròn với bán kính r=2 và 3 Và xuất ra
màn hình toạ độ tâm và bán kính.
vector<Vec3f> circles;
HoughCircles(src, circles, HOUGH_GRADIENT, 1,
src.rows / 17, // change this value to detect circles with different distances to each other
100, 0.9, 1, 4 // change the last two parameters // (min_radius & max_radius) to detect larger circles );
for (size_t i = 0; i < circles.size(); i++)
{
Vec3i c = circles[ ]; Point center = Point(c[ ], c[ ]);
int radius = c[ ]; cout << "Circle: " << i << " Center ( " << center.x << " , " <<
center.y << " ),radius: " << radius << endl;
}
cout << circles.size() << endl;
Trang 24Nhận xét: Có thể thấy kết quả sau khi sử dụng hàm Hough Circle của OpenCV trả
về nhiều kết quả hơn so với tính tay Lí do là vì trong hàm Hough Circle có tích hợp sẵn bộ lọc Canny dẫn đến làm biến dạng ảnh đầu vào Tuy nhiên vẫn có những sự giống nhau về toạ độ tâm và bán kính giữa kết quả tính tay và lập trình
Trang 25HoughCircles(src, circles, HOUGH_GRADIENT, 1,
src.rows / 17, // change this value to detect circles with different distances to each other
100, 0.9, 1, 4 // change the last two parameters // (min_radius & max_radius) to detect larger circles );
for (size_t i = 0; i < circles.size(); i++)
{
Vec3i c = circles[ ]; Point center = Point(c[ ], c[ ]);
// circle center // circle outline int radius = c[ ]; cout << "Circle: " << i << " Center ( " << center.x << " , " <<
center.y << " ),radius: " << radius << endl;
}
cout << circles.size() << endl;
cout << "out put image" << endl << src;
waitKey(0);
Trang 26return 0; }
Trang 27Câu c) Tìm vị trí template trong hình sau sử dụng giải thuật general hough line ( bao gồm scale và xoay):
Trang 28Áp dụng general hough transform để tìm vị trí template1 trong hình ban đầu:
Bước 2 Tìm hướng của Template và Frame
Ta sử dụng 2 kernel để đạo hàm theo hướng x và y:
Trang 30Đối với Frame:
Làm tương tự với Frame ta có :
Ma trận Result khi đạo hàm Frame theo phương x:
Trang 33Ta liệt kê tất cả các tọa độ pixel có cường độ sáng là 1 và tiến hành tính toán theo công
thức:
𝑅𝑋 = 𝑥𝐶 − 𝑥 ; 𝑅𝑌 = 𝑦𝐶 − 𝑦
𝑅 = √𝑅𝑋2 + 𝑅𝑌2 ; 𝛼 = 𝑎𝑟𝑐𝑡𝑎𝑛 𝑅𝑌
𝑅𝑋 Tọa độ 1;1 2;1 3;1 4;1 5;1 6;1 1;2 1;3 1;4 1;5 1;6 2;6 3;6 4;6 5;6 6;6 6;2 6;3 6;4 6;5
Ry 2 2 2 2 2 2 1 0 -1 -2 -3 -3 -3 -3 -3 -3 1 0 -1 -2
Rx 2 1 0 -1 -2 -3 2 2 2 2 2 1 0 -1 -2 -3 -3 -3 -3 -3
R 2,83 2,24 2 2,24 2,83 3,61 2,24 2 2,24 2,83 3,61 3,16 3 3,16 3,61 4,24 3,16 3 3,16 3,61 Alpha 0,79 1,11 1,57 -1,11 -0,79 -0,59 0,46 0 -0,46 -0,79 -0,98 -1,25 1,57 1,25 0,98 0,79 -0,32 0 0,32 0,59 Theta 45 135 0 0 45 135 -45 0 0 45 -45 -135 0 0 -45 -135 -45 0 0 45
Trang 36Số lần xuất hiện của x=3 và y=3 là nhiều nhất nên tâm của hình nằm ở (3,3) Điểm (3,3)
vượt trội về số lần xuất hiện, do đó là tâm của template tìm được trong hình
Vote cho các điểm trên hình 3:
Trang 38*Sử dụng với hệ số scale bằng 2/3, ta được công thức:
𝑋𝐶 = 𝑋𝑖− (𝑅 ∗ cos(𝛼) ∗ cos(𝜃) + 𝑅 ∗ sin(𝛼) ∗ sin(𝜃)) ∗ 𝑠
𝑌𝐶 = 𝑌𝑖 − (𝑅 ∗ cos(𝛼) ∗ sin(𝜃) + 𝑅 ∗ cos(𝜃)) ∗ 𝑠
→ 𝑋𝐶 = 𝑋𝑖 − 𝑅 ∗ cos(𝛼) ∗ 2
3 ; 𝑌𝐶 = 𝑌𝑖− 𝑅 ∗ sin(𝛼) ∗
2 3
Vote các điểm trên hình 1:
Trang 40a 1,57 1,11 1,57
1,11 0,46 0,79 -0,79 -0,46 0 0 0 0 -0,24 -0,32 -0,46 -0,79 1,57 0,79 0,46 0,32 0,24 Thet
Trang 41𝑋𝐶 = 𝑋𝑖− (𝑅 ∗ cos(𝛼) ∗ cos(𝜃) + 𝑅 ∗ sin(𝛼) ∗ sin(𝜃))
𝑌𝐶 = 𝑌𝑖 − (𝑅 ∗ cos(𝛼) ∗ sin(𝜃) + 𝑅 ∗ sin(𝛼) ∗ cos(𝜃))
Trang 4217
Vote các điểm cho hình 4: