Untitled
unknown
plain_text
a year ago
7.9 kB
9
Indexable
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/video/background_segm.hpp>
using namespace cv;
using namespace std;
void track(int, void*);
Mat orjinalGoruntu; // Khai báo biến lưu trữ hình ảnh gốc từ camera
Mat fgMaskMOG2; // Biến lưu trữ hình ảnh nền đã được loại bỏ
Mat griGoruntu, kirpik, or2, kenarlar, aynali; // Các biến hỗ trợ xử lý hình ảnh và hiển thị
int thresh = 140, maxVal = 255; // Ngưỡng và giá trị tối đa cho trackbar
int type = 1, deger = 8; // Các biến khác cho trackbar
int main() {
Ptr<BackgroundSubtractor> pMOG2 = new BackgroundSubtractorMOG2(); // Khởi tạo bộ phân đoạn nền
cv::Rect myRoi(288, 12, 288, 288); // Khai báo vùng quan tâm (ROI)
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(1, 1)); // Khởi tạo phần tử kết cấu cho xử lý hình ảnh
VideoCapture cap;
cap.open(0); // Mở camera
while (1) {
Mat aynali2; // Biến lưu trữ hình ảnh dọc
cap >> orjinalGoruntu; // Chụp hình ảnh từ camera
cv::flip(orjinalGoruntu, aynali, 1); // Lật hình ảnh
cv::rectangle(aynali, myRoi, cv::Scalar(0, 0, 255)); // Vẽ hộp giới hạn trên hình ảnh lật
kirpik = aynali(myRoi); // Cắt ra vùng quan tâm
cvtColor(kirpik, griGoruntu, CV_RGB2GRAY); // Chuyển sang ảnh xám
GaussianBlur(griGoruntu, griGoruntu, Size(23, 23), 0); // Làm mờ Gaussian
namedWindow("ayarla", CV_WINDOW_AUTOSIZE); // Tạo cửa sổ để hiển thị trackbar
createTrackbar("Esik", "ayarla", &thresh, 250, track); // Tạo trackbar cho ngưỡng
createTrackbar("Maksimum", "ayarla", &maxVal, 255, track); // Tạo trackbar cho giá trị tối đa
createTrackbar("Esik Tipi", "ayarla", &type, 4, track); // Tạo trackbar cho loại ngưỡng
createTrackbar("Kenarlar", "ayarla", °er, 100, track); // Tạo trackbar cho cạnh
pMOG2->operator()(kirpik, fgMaskMOG2); // Áp dụng bộ phân đoạn nền lên vùng quan tâm
cv::rectangle(fgMaskMOG2, myRoi, cv::Scalar(0, 0, 255)); // Vẽ hộp giới hạn trên hình ảnh đã phân đoạn
track(0, 0); // Gọi hàm track
imshow("ORJINAL Goruntu", aynali); // Hiển thị hình ảnh gốc
imshow("ArkaPlan Kaldirildi", fgMaskMOG2); // Hiển thị hình ảnh đã loại bỏ nền
imshow("Gri", griGoruntu); // Hiển thị ảnh xám
char key = waitKey(24); // Chờ nhấn phím
if (key == 27) break; // Nếu nhấn ESC thì thoát vòng lặp
}
return 0;
}
void track(int, void*) {
int count = 0; // Đếm số điểm lồi
char a[40]; // Chuỗi lưu trữ số điểm lồi
vector<vector<Point> > contours; // Vector chứa đường viền
vector<Vec4i> hierarchy; // Vector chứa thông tin phân cấp
GaussianBlur(fgMaskMOG2, fgMaskMOG2, Size(27, 27), 3.5, 3.5); // Làm mờ Gaussian
threshold(fgMaskMOG2, fgMaskMOG2, thresh, maxVal, type); // Ngưỡng hóa ảnh
Canny(fgMaskMOG2, kenarlar, deger, deger * 2, 3); // Phát hiện biên
findContours(fgMaskMOG2, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); // Tìm đường viền
Mat cizim = Mat::zeros(kenarlar.size(), CV_8UC3); // Tạo ma trận để vẽ
if (contours.size() > 0) { // Nếu có đường viền được tìm thấy
size_t indexOfBiggestContour = -1; // Chỉ số của đường viền lớn nhất
size_t sizeOfBiggestContour = 0; // Kích thước của đường viền lớn nhất
for (size_t i = 0; i < contours.size(); i++) { // Duyệt qua các đường viền
if (contours[i].size() > sizeOfBiggestContour) { // Nếu kích thước của đường viền lớn hơn
sizeOfBiggestContour = contours[i].size(); // Cập nhật kích thước lớn nhất
indexOfBiggestContour = i; // Cập nhật chỉ số đường viền lớn nhất
}
}
vector<vector<int> > hull(contours.size()); // Vector chứa các đỉnh lồi
vector<vector<Point> > hullPoint(contours.size()); // Vector chứa các điểm đỉnh lồi
vector<vector<Vec4i> > defects(contours.size()); // Vector chứa các khiếm khuyết
vector<vector<Point> > defectPoint(contours.size()); // Vector chứa các điểm khiếm khuyết
vector<vector<Point> > contours_poly(contours.size()); // Vector chứa đường viền xấp xỉ
Point2f rect_point[4]; // Mảng lưu trữ các điểm của hình chữ nhật bao quanh
vector<RotatedRect> minRect(contours.size()); // Vector chứa hình chữ nhật nhỏ nhất
vector<Rect> boundRect(contours.size()); // Vector chứa hình chữ nhật giới hạn
for (size_t i = 0; i < contours.size(); i++) { // Duyệt qua các đường viền
if (contourArea(contours[i]) > 5000) { // Nếu diện tích đường viền lớn hơn 5000
convexHull(contours[i], hull[i], true); // Tìm vùng lồi
convexityDefects(contours[i], hull[i], defects[i]); // Tìm khiếm khuyết
if (indexOfBiggestContour == i) { // Nếu đây là đường viền lớn nhất
minRect[i] = minAreaRect(contours[i]); // Tạo hình chữ nhật bao quanh nhỏ nhất
for (size_t k = 0; k < hull[i].size(); k++) { // Duyệt qua các đỉnh lồi
int ind = hull[i][k]; // Lấy chỉ số của đỉnh lồi
hullPoint[i].push_back(contours[i][ind]); // Thêm điểm vào vector hullPoint
}
count = 0; // Đặt lại số điểm khiếm khuyết
for (size_t k = 0; k < defects[i].size(); k++) { // Duyệt qua các khiếm khuyết
if (defects[i][k][3] > 13 * 256) { // Nếu khoảng cách lớn hơn ngưỡng
int p_start = defects[i][k][0]; // Điểm bắt đầu của khiếm khuyết
int p_end = defects[i][k][1]; // Điểm kết thúc của khiếm khuyết
int p_far = defects[i][k][2]; // Điểm lồi của khiếm khuyết
defectPoint[i].push_back(contours[i][p_far]); // Thêm điểm vào vector defectPoint
circle(griGoruntu, contours[i][p_end], 3, Scalar(0, 255, 0), 2); // Vẽ điểm kết thúc khiếm khuyết
count++; // Tăng biến đếm
}
}
// Đánh số tay
if (count == 1)
strcpy(a, "1");
else if (count == 2)
strcpy(a, "2");
else if (count == 3)
strcpy(a, "3");
else if (count == 4)
strcpy(a, "4");
else if (count == 5 || count == 6)
strcpy(a, "5");
else
strcpy(a, "EL GOSTER");
putText(aynali, a, Point(75, 450), CV_FONT_HERSHEY_SIMPLEX, 3, Scalar(0, 255, 0), 3, 8, false); // Hiển thị số tay
drawContours(cizim, contours, i, Scalar(255, 255, 0), 2, 8, vector<Vec4i>(), 0, Point()); // Vẽ đường viền lớn nhất
drawContours(cizim, hullPoint, i, Scalar(255, 255, 0), 1, 8, vector<Vec4i>(), 0, Point()); // Vẽ đỉnh lồi
drawContours(griGoruntu, hullPoint, i, Scalar(0, 0, 255), 2, 8, vector<Vec4i>(), 0, Point()); // Vẽ đỉnh lồi
approxPolyDP(contours[i], contours_poly[i], 3, false); // Xấp xỉ đường viền
boundRect[i] = boundingRect(contours_poly[i]); // Tạo hình chữ nhật giới hạn
rectangle(griGoruntu, boundRect[i].tl(), boundRect[i].br(), Scalar(255, 0, 0), 2, 8, 0); // Vẽ hình chữ nhật giới hạn
minRect[i].points(rect_point); // Lấy các điểm của hình chữ nhật nhỏ nhất
for (size_t k = 0; k < 4; k++) { // Duyệt qua 4 điểm
line(griGoruntu, rect_point[k], rect_point[(k + 1) % 4], Scalar(0, 255, 0), 2, 8); // Vẽ các cạnh của hình chữ nhật
}
}
}
}
}
imshow("Sonuc", cizim); // Hiển thị kết quả
}
Editor is loading...
Leave a Comment