1. Trang chủ
  2. » Giáo Dục - Đào Tạo

BÀI TẬP-ÔN TẬP CHUYÊN ĐỀ 1 MÔN TIN HỌC

13 388 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 13
Dung lượng 274,18 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

equalizeHistimgin, imgout; Câu 2: Lọc trong không gian.. Ứng dụng lọc làm trơn trong không gian bằng mặt nạ trung bình và mặt nạ Gauss a.. Cơ bản về lọc trong không gian  Ảnh tồn tại tr

Trang 1

ÔN TẬP CHUYÊN ĐỀ 1

Câu 1: Mục đích của việc cân bằng historam? Xây dựng và cài đặt thuật toán cân bằng histogram tự động.

a Mục đích

 Mục đích của cân bằng histogram là làm cho histogram trở nên đồng đều Khi đó ta làm tăng được độ tương phản của ảnh (làm cho ảnh trở nên rõ hơn)

b Xây dựng công thức

 Cân bằng histogram được cho bằng phương trình: s=T(r)=(L-1)

r pr w dw

0 ) ( với pr : Là hàm mật độ xác suất pr(w): Xác suất xảy ra mức xám w

Trong xác suất, tích phân của hàm mật độ là hàm phân phối Công thức trên có w là biến

liên tục, ta không thể lập trình nó Ta phải dùng công thức rời rạc: sk=T(rk)=(L-1)

k j

j

r r p

0 ) ( với k= 0,1,2,…,L-1

c Cài đặt thuật toán

void HistogramEqualization(Matimgin, Matimgout) //Can bang Histogram

{

int M = imgin.size().height;

int N = imgin.size().width;

int x, y;

int r, h[L];

for (r = 0; r < L; r++)

h[r] = 0;

for (x = 0; x < M; x++)

for (y = 0; y < N; y++)

{

r = imgin.at<uchar>(x, y);

h[r]++;

}

double p[L];

for (r = 0; r < L; r++)

p[r] = (double)h[r] / (M*N);

double s[L];

int j, k;

for (k = 0; k < L; k++)

{

s[k] = 0;

for (j = 0; j <= k; j++)

s[k] += p[j];

s[k] *= L - 1;

}

for (x = 0; x < M; x++)

for (y = 0; y < N; y++)

{

r = imgin.at<uchar>(x, y);

Trang 2

imgout.at<uchar>(x, y) = (uchar)s[r];

}

return;

}

d Hàm trong openCV.

equalizeHist(imgin, imgout);

Câu 2: Lọc trong không gian Ứng dụng lọc làm trơn trong không gian bằng mặt nạ trung bình và mặt nạ Gauss

a Cơ bản về lọc trong không gian

 Ảnh tồn tại trong miền không gian, nếu xử lý trong miền không gian thì không được tốt, ta chuyển ảnh sang miền tần số để xử lý, xử lý xong chuyển lại sang miền không gian.

 Người ta dùng một cửa sổ nhỏ để lọc trong không gian, cửa sổ nhỏ thường được gọi là mặt

nạ (mask), tên thông dụng nhất là mặt nạ, opencv thường gọi là Kernels.

b Xây dựng công thức

 Giá trị của bộ lọc người ta sẽ cho tùy vào yêu cầu cụ thể

 Bộ lọc trong không gian được cho bằng phương trình sau: (Sum Convolution)

g (x , y )=w (−1,−1 ) f ( x−1, y−1)+w (−1,0 ) f ( x−1, y )+…+w (0,0) f ( x , y )+…+w (1,1) f (x +1, y+1)

Kích thước bộ lọc thường là số lẻ để có phần tử trung tâm (3x3 hoặc 5x5)

 Tổng quát lọc trong không gian được cho bằng phương trình :

g(x,y)=

aa

b b t

t y s x f t s

w( , ) ( , )

Trong đó :

mxn là kích thước của bộ lọc

a=m/2 và b=n/2

w(s,t) là mặt nạ lọc hay bộ lọc

f(x,y) là điểm ảnh đầu vào

g(x,y) là điểm ảnh đầu ra

Phép toán lọc trong không gian được gọi là tổng chập (convolution).

Đối với lọc tuyến tính, mặt nạ lọc thường dùng là mặt nạ trung bình hay mặt nạ Gauss Mặt nạ càng lớn, ảnh càng bị nhòe.

Trang 3

Ví dụ: mặt nạ lọc trung bình và mặt nạ Gauss:

c Cài đặt thuật toán

void MyFilter2D(Matimgin, Mat imgout, Matw)

{

int m = w.size().height;

int n = w.size().width;

int M = imgin.size().height;

int N = imgin.size().width;

int x, y, s, t;

int a = m / 2, b = m / 2;

float r;

for (x = a; x < M - a; x++)

for (y = b; y < N - b; y++)

{

r = 0;

for (s = -a; s <= a; s++) for (t = -b; t <= b; t++)

r += w.at<float>(s + a, t + b) *imgin.at<uchar>(x + s, y + t);

imgout.at<uchar>(x, y) = (uchar)r;

}

return;

} //Có sẵn hàm filter2D trong VS

void SmoothingLinearFilter(Matimgin, Matimgout)

{

int m = 15, n = 15;

Mat w = Mat(m, n, CV_32FC1);

int x, y;

for (x = 0; x < m; x++)

for (y = 0; y < n; y++)

w.at<float>(x, y) = 1.0 / (m*n);

//MyFilter2D(imgin, imgout, w);

filter2D(imgin, imgout, CV_8UC1, w);

return;

}

d Hàm trong openCV

blur(imgin, imgout, Size (35, 35));

GaussianBlur(imgin, imgout, Size (0,0),5);

Câu 3: Các bước lọc ảnh trong miền tần số (7 bước) Xóa nhiễu Morie

a Các bước lọc ảnh trong miền tần số:

- Bước 1: Cho ảnh đầu vào f(x,y) có kích thước MxN Mở rộng ảnh có kích thước là PxQ

Cụ thể P=2M, Q=2N.

- Bước 2: Thêm zero (số 0) vào phần mở rộng, ta được ảnh fp(x,y).

16 1

x

x

9

Trang 4

- Bước 3: Nhân fp(x,y) với (-1)x+y để dời F(0,0) vào tâm ảnh Do ảnh là số thực nên phổ luôn luôn đối xứng.

- Bước 4: Biến đổi Fourier của ảnh ở Bước 3 ta được F(u,v).

- Bước 5: Tạo hàm lọc đối xứng, có giá trị thực H(u,v), có kích thước là PxQ, có tâm là (P/2,Q/2) Thực hiện phép nhân G(u,v) = F(u,v)*H(u,v).

- Bước 6: Thu được ảnh đã xử lý bằng biến đổi Fourier ngược, lấy phần thực và dời trở lại gốc tọa độ

- Bước 7: Bỏ phần đã mở rộng, ta thu được ảnh g(x,y) có kích thước MxN.

Biểu diễn bằng sơ đồ khối:

b Xóa nhiễu Moire

void MoireRemove(Matimgin, Matimgout)

{

int M = imgin.size().height;

int N = imgin.size().width;

//1 Mo rong anh co kich thuoc PxQ

int P = getOptimalDFTSize(M);

int Q = getOptimalDFTSize(N);

//2.Them 0 vao phan mo trong

Mat f = Mat(P, Q, CV_32FC2, CV_RGB(0, 0, 0));

//3

int x, y, u, v;

for (x = 0; x < M; x++)

for (y = 0; y < N; y++)

if ((x + y) % 2 == 0)

f.at<Vec2f>(x, y)[0] = 1.0*imgin.at<uchar>(x, y);

else

f.at<Vec2f>(x, y)[0] = -1.0*imgin.at<uchar>(x, y);

//Buoc 4: Bien doi Fourier

Mat F = Mat(P, Q, CV_32FC2, CV_RGB(0, 0, 0));

dft(f, F);

//Buoc 5: Tao ham loc, va nhan H(u,v) vs F(u,v)

Mat H = Mat(P, Q, CV_32FC2, CV_RGB(0, 0, 0));

int u1 = 45, v1 = 58;

Trang 5

int u2 = 40, v2 = 119;

int u3 = 86, v3 = 58;

int u4 = 82, v4 = 119;

double D01 = 5, D02 = 5, D03 = 15, D04 = 15;

double Duv, DuvTru;

double responese;

for (u = 0; u < P; u++)

for (v = 0; v < Q; v++)

{

Duv = sqrt(1.0*(u - u1)*(u - u1) + 1.0*(v - v1)*(v - v1));

DuvTru = sqrt(1.0*(u - P + u1)*(u - P + u1) + 1.0*(v - Q + v1)*(v - Q + v1)); responese = (1 / (1 + pow(D01 / Duv, 2 * 2)))*(1 / (1 + pow(D01 / DuvTru, 2 * 2)));

Duv = sqrt(1.0*(u - u2)*(u - u2) + 1.0*(v - v2)*(v - v2));

DuvTru = sqrt(1.0*(u - P + u2)*(u - P + u2) + 1.0*(v - Q + v2)*(v - Q + v2)); responese *= (1 / (1 + pow(D02 / Duv, 2 * 2)))*(1 / (1 + pow(D02 / DuvTru, 2 * 2)));

Duv = sqrt(1.0*(u - u3)*(u - u3) + 1.0*(v - v3)*(v - v3));

DuvTru = sqrt(1.0*(u - P + u3)*(u - P + u3) + 1.0*(v - Q + v3)*(v - Q + v3)); responese *= (1 / (1 + pow(D03 / Duv, 2 * 2)))*(1 / (1 + pow(D03 / DuvTru, 2 * 2)));

Duv = sqrt(1.0*(u - u4)*(u - u4) + 1.0*(v - v4)*(v - v4));

DuvTru = sqrt(1.0*(u - P + u4)*(u - P + u4) + 1.0*(v - Q + v4)*(v - Q + v4)); responese *= (1 / (1 + pow(D04 / Duv, 2 * 2)))*(1 / (1 + pow(D04 / DuvTru, 2 * 2)));

H.at<Vec2f>(u, v)[0] = responese;

}

Mat G = Mat(P, Q, CV_32FC2, CV_RGB(0, 0, 0));

mulSpectrums(F, H, G, DFT_ROWS);

//Buoc 6,7: Bien doi Fourier nguoc

Mat g = Mat(P, Q, CV_32FC2, CV_RGB(0, 0, 0));

idft(G, g, DFT_SCALE);

//doi tam anh lai

float r;

for (x = 0; x < M; x++)

for (y = 0; y < N; y++)

{

if ((x + y) % 2 == 0)

r = g.at<Vec2f>(x, y)[0];

else

r = -g.at<Vec2f>(x, y)[0];

if (r < 0)

r = 0;

if (r>L - 1)

r = L - 1;

imgout.at<uchar>(x, y) = (uchar)r;

}

}

Trang 6

Câu 4: Xây dựng và cài đặt thuật toán nhận dạng khuôn mặt dùng phương pháp khuôn mặt riêng (eigenface)

Các bước nhận dạng khuôn mặt.

Bước 1: Phát hiện khuôn măt dùng thuật toán và file xml có sẵn trong openCV Dùng Detect and Display().

Bước 2: Tạo cơ sở dữ liệu gồm 15 mặt, trong đó 10 mặt dùng để học, 5 mặt dùng để nhận dạng.

Bước 3: Nhận dạng dùng eigenface.

void detectAndDisplay(Mat frame, int c);

void detectAndDisplayAndRecognition(Mat frame, int c);

String face_cascade_name = "haarcascade_frontalface_alt.xml";

CascadeClassifier face_cascade;

string window_name = "Capture - Face detection";

RNG rng(12345);

Ptr<FaceRecognizer> model;

int GetImage(void)

{

VideoCapture capture(0);

Mat frame;

// 1 Load the cascades

if (!face_cascade.load(face_cascade_name)){ printf(" (!)Error loading\n"); return -1; };

// 2 Read the video stream

if (capture.isOpened())

{

namedWindow(window_name, WINDOW_AUTOSIZE);

waitKey(1000);

for (;;) {

capture >> frame;

int c = waitKey(10);

if (c == 27)

break; // 3 Apply the classifier to the frame

if (!frame.empty()) {

detectAndDisplay(frame,c);

} else {

printf(" (!) No captured frame Break!");

break; }

} }

return 0;

}

Trang 7

void detectAndDisplay(Matframe, intc)

{

std::vector<Rect> faces;

Mat frame_gray;

static int count = 1;

char filename[64];

cvtColor(frame, frame_gray, COLOR_BGR2GRAY);

equalizeHist(frame_gray, frame_gray);

// Detect faces

face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));

for (size_t i = 0; i < faces.size(); i++)

{

Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

Mat faceROI = frame_gray(faces[i]);

if (c == 'A' || c == 'a') {

sprintf(filename, "data\\Linh\\%02d.bmp", count++);

imwrite(filename, faceROI);

} }

// Show what you got

imshow(window_name, frame);

}

void Training(void)

{

vector<Mat> images;

vector<int> labels;

char filename[64];

for (int i = 1; i <= 10; i++)

{

sprintf(filename, "data\\Duyen\\%02d.bmp", i);

Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);

resize(img, img, Size(100, 100));

images.push_back(img);

labels.push_back(1);

}

for (int i = 1; i <= 10; i++)

{

sprintf(filename, "data\\Anh\\%02d.bmp", i);

Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);

resize(img, img, Size(100, 100));

images.push_back(img);

labels.push_back(2);

}

for (int i = 1; i <= 10; i++)

{

Trang 8

sprintf(filename, "data\\Linh\\%02d.bmp", i);

Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);

resize(img, img, Size(100, 100));

images.push_back(img);

labels.push_back(3);

}

//traning

model = createEigenFaceRecognizer();

model->train(images, labels);

model->save("face.xml");

return;

}

void detectAndDisplayAndRecognition(Matframe, intc)

{

std::vector<Rect> faces;

Mat frame_gray;

static int count = 1;

char s[64];

int predictLabel;

double confidence;

cvtColor(frame, frame_gray, COLOR_BGR2GRAY);

equalizeHist(frame_gray, frame_gray);

// Detect faces

face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));

for (size_t i = 0; i < faces.size(); i++)

{

Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

Mat faceROI = frame_gray(faces[i]);

if (c == 'A' || c == 'a') {

resize(faceROI, faceROI, Size(100, 100));

predictLabel = -1;

confidence = 0.0;

model->predict(faceROI, predictLabel, confidence);

sprintf(s, "%d %.2f", predictLabel, confidence);

putText(faceROI, s, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255));

imshow("Recognition", faceROI);

if (predictLabel == 1) {

sprintf(s, "Duyen %.2f", confidence);

putText(faceROI, s, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255));

imshow("Recognition", faceROI);

Trang 9

} else if (predictLabel == 2) {

sprintf(s, "Anh %.2f", confidence);

putText(faceROI, s, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255));

imshow("Recognition", faceROI);

} else {

sprintf(s, "Linh %.2f", confidence);

putText(faceROI, s, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255));

imshow("Recognition", faceROI);

} }

}

// Show what you got

imshow(window_name, frame);

}

int Recognition(void)

{

namedWindow("Recognition", WINDOW_AUTOSIZE);

model = createEigenFaceRecognizer();

model->load("face.xml");

VideoCapture capture(0);

Mat frame;

// 1 Load the cascades

if (!face_cascade.load(face_cascade_name)){ printf(" (!)Error loading\n"); return -1; };

// 2 Read the video stream

if (capture.isOpened())

{

namedWindow(window_name, WINDOW_AUTOSIZE);

waitKey(1000);

for (;;) {

capture >> frame;

int c = waitKey(10);

if (c == 27)

break; // 3 Apply the classifier to the frame

if (!frame.empty()) {

detectAndDisplayAndRecognition(frame, c);

} else {

printf(" (!) No captured frame Break!");

break;

Trang 10

} }

}

return 0;

}

int main(void)

{

//GetImage(); //không cần hàm này cũng được…

//Training();

Recognition();

return 0;

}

Phương pháp phát hiện và nhận dạng đối tượng trong ảnh, cụ thể là nhận dạng khuôn mặt

- Có 2 bước chính là phát hiện và nhận dạng

B1: phát hiện - detect

Có 3 phương pháp trích đặc điểm thông dụng là Haar-like, LBP (Local Binary Pattern) và HOG (Histogram Orient Gradient)

Ta phải tạo ra file xml Phương pháp tạo ra file xml Ta dùng công cụ Haar-kit ở

http://robotik.inflomatik.info

a/ Ta phải có khoảng 1500 ảnh chứa đối tượng cần nhận dạng, ta gọi là ảnh dương, đối tượng ở trong nền ra

phức tạp

2000 ảnh không chứa đối tượng (ảnh nền), và ta gọi là ảnh âm Dùng file objectmarker.exe để đánh dấu ảnh dương, kết quả lưu trong file info.txt

tenfil 1 x y width heigh b/ Dùng createsamples.exe hoặc opencv_createsamples.exe

(C:\opencv\build\x86\VC10\bin) để tạo ra

file hand.vec

c/ Dùng opencv_traincascade.exe để đọc ảnh dương đã đánh dấu và ảnh âm để tạo ra file xml

thời gian chạy bước c khoảng 1 ngày rưỡi trên máy P 4, 3.2GHz

B2: Nhận dạng

Nói rồi bài nhận dạng bàn tay hôm trước @~@ OMG!!!!

5 ANH NHIN THANG QUA TRA QUA PHAI NHIN LEN NHIN XUONG

khoanh khuon mat roi moi nhan chu a de chup

void detectAndDisplay( Mat frame, int c);

void detectAndDisplayAndRecognation( Mat frame, int c);

Ptr < FaceRecognizer > model;

String face_cascade_name = "haarcascade_frontalface_alt.xml";

//String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";

CascadeClassifier face_cascade;

//CascadeClassifier eyes_cascade;

string window_name = "Capture - Face detection";

RNG rng(12345);

Trang 11

int GetImage( void )

{

VideoCapture capture(0);

Mat frame;

if (!face_cascade.load(face_cascade_name)){ printf(" (!)Error loading\n"); return -1; };

//if (!eyes_cascade.load(eyes_cascade_name)){ printf(" (!)Error loading\n"); return -1; };

if (capture.isOpened())

{

namedWindow(window_name, WINDOW_AUTOSIZE );

for (;;) {

capture >> frame;

int c = waitKey(10);

if (c == 27)

break ;

if (!frame.empty())

detectAndDisplay(frame,c);

else

{

printf(" (!) No captured frame Break!");

break ; }

} }

return 0;

}

void detectAndDisplay( Mat frame , int c )

{

std:: vector < Rect > faces;

Mat frame_gray;

static int count = 13;

char filename[64];

cvtColor( frame , frame_gray, COLOR_BGR2GRAY );

equalizeHist(frame_gray, frame_gray);

face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE , Size (30, 30));

for ( size_t i = 0; i < faces.size(); i++)

{

Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);

ellipse( frame , center, Size (faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar (255, 0, 255), 2, 8, 0);

Mat faceROI = frame_gray(faces[i]);

if ( c == 'A' || c == 'a'){

sprintf(filename, "data\\DaiDong\\%02d.bmp", count++);

imwrite(filename, faceROI);

} }

imshow(window_name, frame );

}

void detectAndDisplayAndRecognation( Mat frame , int c )

{

std:: vector < Rect > faces;

Mat frame_gray;

static int count = 13;

Ngày đăng: 17/05/2015, 11:23

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w