markdown:
## Giới thiệu
SVM là mô hình được sử dụng trong nhiều ngành, là một mô hình máy học giám sát được dùng để phân tích, phân lớp dữ liệu. Có thể những điều ở đây khá trừ tượng. Trong bài viết này, tôi sẽ giới thiệu một cách tổng quan về mô hình SVM và ví dụ về SVM trong OPenCV.
## Tiền đề bài viết
Bài viết nằm trong loạt bài viết chương trình Tự Học OpenCV Qua Các Ví Dụ Thực Tế của
[STDIO](http://www.stdio.vn). Kiến thức trong bài viết này rất quan trọng trong việc hoàn thành ứng dụng nhận diện biển số xe và nhận diện chữ viết tay,...
## Đối tượng hướng đến
Bài viết hướng tới các bạn đọc mới tìm hiểu về xử lý ảnh, đặc biệt là với OpenCV và chưa có kiến thức tương đương.
Trong bài viết này tôi sử dụng
** Windows 10 (64-bit),** **Visual Stdio 2013 Ultimate** và ** OpenCV 3.0**.
## SVM là gì?
SVM (Support Vector Machine) là một khái niệm trong thống kê và khoa học máy tính cho một tập hợp các phương pháp học có giám sát liên quan đến nhau để phân loại và phân tích hồi quy.
SVM là một thuật toán phân loại nhị phân, SVM nhận dữ liệu vào và phân loại chúng vào hai lớp khác nhau. Với một bộ các ví dụ luyện tập thuộc hai thể loại cho trước, thuật toán luyện tập SVM xây dựng một mô hình SVM để phân loại các ví dụ khác vào hai thể loại đó.
## Ví dụ về SVM tuyến tính
Tôi có một khôn gian có nhiều điểm và các kí hiệu như sau:
Phân tích
**y**: Đây là các lớp (Bản lề) chứa các điểm dữ liệu i **x**. Ở ví dụ này mang giá trị 1 và -1. i **x**: Là một vector thực nhiều chiều (p chiều). i
- Nhiệm vụ là cần phải tìm một
**siêu phẳng**(Optimal hyperplane) có lề lớn nhất chia tách các điểm dữ liệu có ban đầu để huấn luyện và các điểm sau này. Mỗi siêu phẳng (Optimal hyperplane) đều có thể được viết dưới dạng một tập các điểm thỏa mãn:
w.x-b = 0
**w**: Là một vectơ pháp tuyến của siêu phẳng (Optimal hyperplane).
- Tham số
**xác định khoảng cách giữa gốc tọa độ và siêu phẳng theo hướng vectơ pháp tuyến** b/ ||w|| **w**.
- Như bạn có thể thấy ở hình s1. Tôi giả sử có tới 3 siêu phẳng (Optimal hyperplane) là
**H1**(Xanh dương), **H2**(Đỏ), **H3**(Xanh lá). **H3**sẽ bị loại đầu tiên vì không thể phân loại các điểm huấn luyện cho trước. **H1**bị loại vì khoảng cách từ các điểm Support Vector đến siêu phẳng (Optimal hyperplane) chưa phải là cực đại. **H2**là siêu phẳng cần tìm. Lúc này các siêu phẳng đó được xác định:
w.x - b = 1
và
w.x - b = -1
- Các điểm dữ liệu cho trước nằm trên các siêu phẳng song song được gọi là Support Vector.
Tổng quan
- SVM là mô hình xây dựng một siêu phẳng hoặc một tập hợp các siêu phẳng trong một không gian nhiều chiều hoặc vô hạn chiều, có thể được sử dụng cho phân loại, hồi quy, hoặc các nhiệm vụ khác. Để phân loại tốt nhất thì phải xác định siêu phẳng (Optimal hyperplane) nằm ở càng xa các điểm dữ liệu của tất cả các lớp (Hàm lề) càng tốt, vì nói chung lề càng lớn thì sai số tổng quát hóa của thuật toán phân loại càng bé.
- Muốn các điểm dữ liệu có thể được chia tách một cách tuyến tính, thì bạn phải cần chọn hai siêu phẳng của lề sao cho không có điểm nào ở giữa chúng và khoảng cách giữa chúng là tối đa.
- Trong nhiều trường hợp, không thể phân chia các lớp dữ liệu một cách tuyến tính trong một không gian ban đầu được dùng để mô tả một vấn đề. Vì vậy, nhiều khi cần phải ánh xạ các điểm dữ liệu trong không gian ban đầu vào một không gian mới nhiều chiều hơn, để việc phân tách chúng trở nên dễ dàng hơn trong không gian mới. Chú ý: Trong bài viết này, tôi chỉ giới thiệu tổng quan về mô hình SVM và SVM trong OpenCV được sử dụng như thế nào? Vì vậy, tôi không đi sâu vào nội dung này. Bạn có thể tham khảo tại mục Tham khảo hoặc các bài viết tiếp theo của Stdio.vn ::
[www.stdio.vn](http://www.stdio.vn).
Với các điểm tổng quan ở trên thì nhiệm vụ chính là phân loại thống kế.
- Thuật toán được cho trước một số điểm dữ liệu cùng với nhãn của chúng thuộc các lớp cho trước (Huấn luyện).
- Mục tiêu của thuật toán là xác định xem một điểm dữ liệu mới sẽ được thuộc về lớp nào (Phân loại).
## SVM trong OpenCV
### Source code
#include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include "opencv2/imgcodecs.hpp" #include <opencv2/highgui.hpp> #include <opencv2/ml.hpp> using namespace cv; using namespace cv::ml; int main(int, char**) { int width = 512, height = 512; Mat image = Mat::zeros(height, width, CV_8UC3); int labels[4] = { 1, 1, 1, -1 }; Mat labelsMat(4, 1, CV_32SC1, labels); float trainingData[4][2] = { { 501, 10 }, { 255, 10 }, { 501, 255 }, { 10, 501 } }; Mat trainingDataMat(4, 2, CV_32FC1, trainingData); Ptr<ml::SVM> svm = ml::SVM::create(); svm->setType(ml::SVM::C_SVC); svm->setKernel(ml::SVM::LINEAR); svm->setTermCriteria(cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6)); svm->train(trainingDataMat, ml::ROW_SAMPLE, labelsMat); Vec3b green(0, 255, 0), blue(255, 0, 0); for (int i = 0; i < image.rows; ++i) for (int j = 0; j < image.cols; ++j) { Mat sampleMat = (Mat_<float>(1, 2) << j, i); float response = svm->predict(sampleMat); if (response == 1) image.at<Vec3b>(i, j) = green; else if (response == -1) image.at<Vec3b>(i, j) = blue; } int thickness = -1; int lineType = 8; circle(image, Point(501, 10), 5, Scalar(0, 0, 0), thickness, lineType); // black circle(image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType); // white circle(image, Point(501, 255), 5, Scalar(0, 0, 255), thickness, lineType); // red circle(image, Point(10, 501), 5, Scalar(0, 255, 0), thickness, lineType); // green imshow("SVM Simple Example", image); waitKey(0); }
### Phân tích
#### Thiết lập dữ liệu huấn luyện
float labels[4] = {1.0, -1.0, -1.0, -1.0}; float trainingData[4][2] = {{501, 10}, {255, 10}, {501, 255}, {10, 501}};
Dữ liệu được huấn luyện được tạo thành bởi một tập điểm có giá trị 2D. Ở đoạn code trên, tôi có:
- 2 lớp: Lớp thứ nhất mang giá trị -1, và lớp thứ hai mang giá trị 1 (lables).
- 4 điểm dữ liệu (Điểm được dùng để huấn luyện mô hình SVM) cho trước ứng với giá trị của lớp: (501, 10) thuộc lớp thứ hai, và 3 điểm còn lại thuộc lớp thứ nhất.
Chú ý: Số lượng phần tử của ma trận labels bằng với số cột của ma trận của trainingData.
Mat trainingDataMat(4, 2, CV_32FC1, trainingData); Mat labelsMat(4, 1, CV_32FC1, labels);
Chú ý: Hàm CvSVM::train() sử dụng kiểu dữ liệu truyền vào là kiểu Mat.
#### Thiết lập thông số của SVM
// Set up SVM's parameters Ptr<ml::SVM> svm = ml::SVM::create(); svm->setType(ml::SVM::C_SVC); svm->setKernel(ml::SVM::LINEAR); svm->setTermCriteria(cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6));
Phân tích
- Type SVM: Tôi chọn ml::SVM::C_SVC để có thể được sử dụng để phân loại nhiều (n) lớp (n>2). Tham số này được xác định trong thuộc tính ml::SVM::Params.svmType. Lưu ý: Chức năng quan trọng của loại SVM CvSVM::C_SVC là tách hoàn hảo của các lớp học (Tức là khi dữ liệu đào tạo là không bị phân chia qua các lớp khác).
- Type SVM kernel: Là một tham số này được xác định trong thuộc tính ml::SVM.KernelType.
- Termination criteria of the algorithm: Là một tham số này được định nghĩa trong một cấu trúc cv::TermCriteria.
Chú ý: Như ở phần Đối tượng hướng đến trong bài viết. Tôi sử dụng OpenCV 3.0. Với các phiên bản khác của OpenCV, để thiết lập thông số cho SVM sẽ có cách hiện thực khác.
#### Huấn luyện SVM
Để xây dựng mô hình huấn luyện SVM, tôi sử dụng phương thức CvSVM::train().
CvSVM SVM; SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
Như vậy tôi đã huấn luyện xong cho mô hình SVM của ví dụ ở trên.
#### Phân loại lớp (Bản lề)
Phương pháp CvSVM::predict() được sử dụng để phân loại một mẫu đầu vào bằng cách sử dụng một SVM được huấn luyện.
Vec3b green(0,255,0), blue (255,0,0); for (int i = 0; i < image.rows; ++i) { for (int j = 0; j < image.cols; ++j) { Mat sampleMat = (Mat_<float>(1,2) << i,j); float response = SVM.predict(sampleMat); if (response == 1) image.at<Vec3b>(j, i) = green; else if (response == -1) image.at<Vec3b>(j, i) = blue; } }
Như bạn thấy ở trên, đây chính là kết quả của đoạn code trên.
- Với các điểm tròn nhỏ màu đen, trắng, đỏ, xanh lá cây: Đây chính là các điểm dữ liệu cho trước.
- Ranh giới giữa màu xanh lá cây và xanh dương: Đây chính là siêu phẳng (Optimal hyperplane) của mô hình SVM. Bạn có thể thấy rằng, khoảng cách giữa điểm tròn xanh lá cây tới siêu phẳng (Optimal hyperplane) sẽ bằng khoảng cách giữa điểm tròn màu đỏ tớisiêu phẳng (Optimal hyperplane) (Tương tự với điểm tròn màu trắng).
- Dòng 6: Là một cách khởi tạo một ma trận, nó sẽ có giá trị như sau: sampleMat = [i, j]. Ví dụ: Mat M = (Mat_(2,4) << 1, 0, 0, 0, 1, 0, 0, 0;. Kết quả là M = [1, 0, 0, 0, 1, 0, 0, 0])
- Vậy là đoạn code ở trên sẽ phân loại các điểm dữ liệu thuộc vào lớp nào trên mô hình SVM mà tôi đã huấn luyện ở trên.
#### Support Vector
Trong OpenCV 3.0, để có thể lấy được các điểm Support Vector thì sử dụng phương thức SVM::getSupportVectors(). Kiểu trả về ở đây là một Mat, với số hàng (Rows) chính là số lượng của các điểm Support Vector
## Tổng kết
Trong bài viết này, tôi đã giới thiệu sơ qua về mô hình SVM cũng như ví dụ về hoạt động của SVM trong OpenCV. Ứng dụng của SVM trong các lĩnh vực nói chung là rất nhiều. Ở trong xử lý ảnh, SVM cũng tác dụng to lớn nhiều trong các ứng dụng như trong ứng dụng nhận dạng ký tự viết tay, nhận dạng biển số xe,...
Mọi thắc mắc có thể bình luận tại bài viết hoặc liên hệ với
[Trương Đạt](http://www.stdio.vn/users/index/11/truong-dat).
## Tham khảo
http://docs.opencv.org/
https://en.wikipedia.org/wiki/Support_vector_machine
THẢO LUẬN

Server: LiteSpeed


markdown:
|
|
## 1.5T Con đội quay tay Sata 97-831 (97831)
|Nhãn hàng:||
|
Thương hiệu dụng cụ cầm tay SATA là một trong những thương hiệu công cụ cầm tay hàng đầu sở hữu bởi Apex Tool Group, sản xuất sản phẩm
**1.5T Con đội quay tay Sata 97-831 (97831)**. Apex Tool Group được thành lập vào tháng 7 năm 2010 như là một liên doanh giữa hai nhà sản xuất công cụ hàng đầu là Tập Đoàn Danaher và Cooper Tools. Được định hướng bởi một đội ngũ lãnh đạo mạnh mẽ và dày dạn kinh nghiệp, các công ty mới được dành để cung cấp cho khách hàng của mình với các sản phẩm xuất sắc, giao hàng kịp thời, và dịch vụ khách hàng đó là không ai sánh kịp. Apex Tool Group là cam kết để luôn luôn đổi mới sản phẩm **1.5T Con đội quay tay Sata 97-831 (97831)** bằng cách lắng nghe khách hàng và để cải tiến liên tục trong tất cả mọi thứ chúng tôi làm.
Trụ sở chính tại Sparks (North Baltimore), Maryland, Mỹ, Apex Tool Group hoạt động tại hơn 30 quốc gia trên thế giới, nhân viên đạt đến 7.600 với doanh thu hàng năm vào khoảng 1.5 tỷ USD.
Dụng cụ cầm tay SATA đáp ứng hoặc vượt quá tiêu chuẩn ANSI và tiêu chuẩn DIN với các sản phẩm
**1.5T Con đội quay tay Sata 97-831 (97831)** cung cấp cho các bạn, với một mức giá rất phải chăng.
Nhà máy sản xuất công cụ SATA đạt tiên chuẩn ISO 9001 và Apex Tool Group cung cấp bảo hành suốt đời đối với các sản phẩm của SATA Tools trong đó có
**1.5T Con đội quay tay Sata 97-831 (97831)**.

WARC-Type: response

Content-Type: application/http; msgtype=response

Connection: close

Pragma: no-cache

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Vary: Accept-Encoding,User-Agent

Content-Type: text/html


markdown:
## Tin bất động sản cập nhật
[Kinh nghiệm tìm thuê chung cư giá rẻ tại TP.HCM](/tin-tuc/2016/12/bi-quyet-tim-thue-chung-cu-gia-re/)
Dân số không ngừng gia tăng kéo theo đó là nhu cầu nhà ở cũng tăng cao. Tại Việt Nam hiện nay, bình quân thu nhập đầu người và giá cả rao bán nhà đất luôn có sự chênh lệch khá lớn, không phải ai cũng đủ khả năng mua nhà. Vì vậy, thuê nhà, thuê chung cư để ở đang là giải pháp chung cho vấn đề xã hội bức thiết này.
[Muôn kiểu lừa đảo phòng trọ sinh viên tại TP.HCM](/tin-tuc/2016/12/muon-kieu-lua-dao-phong-tro-sinh-vien-tai-tphcm/)
Thuê được phòng trọ, nhà trọ giá rẻ là mong ước của tất cả sinh viên xa quê đến thành phố Hồ Chí Minh học tập. Tuy nhiên, để tìm được phòng trọ, nhà trọ tốt, giá cả phải chăng không phải điều đơn giản.
[Nhà trọ sinh viên: 4 bước để thuê căn nhà ưng ý](/tin-tuc/2016/09/nha-tro-sinh-vien-tim-nha-ung-y/)
Một năm học mới lại đến, các bạn tân sinh viên từ khắp các tỉnh thành đổ về những đô thị lớn để chuẩn bị cho năm học Đại học đầu tiên của mình. Bên cạnh những bỡ ngỡ của một cuộc sống tự lập xa gia đình, việc tìm kiếm chỗ trọ an ninh với giá cả hợp lý luôn là một khó khăn lớn với các bạn sinh viên.
**Xác định khu vực ở và giá thuê**/ **Tìm kiếm thông tin**/ **Tìm người ở ghép**

WARC-Truncated: length

X-XSS-Protection: 1; mode=block

X-Powered-By: Phusion Passenger

Server: nginx + Phusion Passenger

X-Content-Type-Options: nosniff

Cache-Control: max-age=0, private, must-revalidate

X-Frame-Options: SAMEORIGIN

Strict-Transport-Security: max-age=31536000; includeSubDomains

Vary: Accept-Encoding

Content-Type: text/html; charset=utf-8