Last active
August 29, 2015 14:11
-
-
Save yonghanjung/7b454cdeae883fe4f6da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// g++ -std=c++11 $(pkg-config --cflags --libs opencv) Letter_Detect_ver0.0.cpp -o letter | |
// "A" 2, 6, 7, 85, 10 | |
// "B", 1, 3, 6, 7, 8, 10 | |
// "C" 1, 3, 7, 10 | |
// "D" 0, 2, 3, 4, 5, 6, 7, 8, 10 | |
// "E": 1, 3, 4, 5, 7, 8, 9, 10 | |
/* ============== Library ================= */ | |
#include <opencv2/opencv.hpp> | |
#include <opencv2/core.hpp> | |
#include <opencv/highgui.h> | |
#include <algorithm> // std::sort | |
#include <vector> // std::sort | |
using namespace std; | |
using namespace cv; | |
/* ============== Functions ================= */ | |
/* ------------ Image Editing ------------- */ | |
Mat Crop_Image(Mat img, int Idx){ | |
/* | |
- Function | |
: Cropping the input image and return the index image from cropped image list | |
- Input | |
: Image needed to be cropped | |
: Idx : Index number of the cropped image list | |
- Output | |
: Cropped Image | |
*/ | |
vector<Rect> boundRect; | |
Mat img_gray, img_sobel, img_threshold, element; | |
cvtColor(img, img_gray, CV_BGR2GRAY); // Convert img to gray scale | |
Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, BORDER_DEFAULT); // edge detection : img_sobel | |
threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY); // Img segmentation | |
// element = getStructuringElement(MORPH_RECT, Size(30, 20) ); // erosion, dialiation | |
element = getStructuringElement(MORPH_ELLIPSE, Size(50, 40) ); // erosion, dialiation | |
morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element); //Does the trick | |
vector< vector< Point> > contours; | |
findContours(img_threshold, contours, 0, 1); // find countours | |
vector< vector<Point> > contours_poly( contours.size() ); | |
for( int i = 0; i < contours.size(); i++ ) | |
if (contours[i].size()>100) | |
{ | |
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); | |
Rect appRect( boundingRect( Mat(contours_poly[i]) )); | |
if (appRect.width>appRect.height) | |
boundRect.push_back(appRect); | |
} | |
Mat CroppedImg = img(boundRect[Idx]); | |
return CroppedImg; | |
} | |
Mat Black_White(Mat CroppedImg1){ | |
/* | |
- Function | |
: Input image binarization | |
- Input | |
: Any image | |
- Output | |
; Binarized Image file | |
*/ | |
cvtColor(CroppedImg1, CroppedImg1, CV_BGR2GRAY); | |
blur( CroppedImg1, CroppedImg1, Size(3,3) ); | |
CroppedImg1 = CroppedImg1 > 128; | |
return CroppedImg1; | |
} | |
vector< vector<int> > Image_Fixel(Mat img){ | |
/* | |
- Function | |
: Image to the pixel matrix | |
- Input | |
: Any image | |
- Output | |
: Pixel Matrix | |
*/ | |
Size s = img.size(); | |
int rows = s.height; | |
int cols = s.width; | |
vector< vector<int> > ImgMatrix; | |
vector<int> ImgRow; | |
for (int row_idx = 0; row_idx < rows; row_idx++){ | |
for (int col_idx = 0; col_idx < cols; col_idx++){ | |
ImgRow.push_back(img.at<uchar>(row_idx, col_idx) + 1 - 1); | |
// cout << CroppedImg.at<uchar>(row_idx, col_idx) + 1 - 1 << " "; | |
} | |
ImgMatrix.push_back(ImgRow); | |
ImgRow.clear(); | |
// cout << endl; | |
} | |
return ImgMatrix; | |
} | |
vector<Mat> Cropped_Vector_Construction(string A_Image, int Num_Img){ | |
Mat Crop_Image(Mat , int ); | |
vector<Mat> Cropped_Img_Set; | |
Mat Raw_Image_A = imread(A_Image); | |
Mat CroppedImg; | |
for (int idx = 0; idx < Num_Img; idx ++ ){ | |
CroppedImg = Crop_Image(Raw_Image_A, idx); | |
Cropped_Img_Set.push_back(CroppedImg); | |
} | |
return Cropped_Img_Set; | |
} | |
/* ------------ Print Function ------------- */ | |
void Print_Matrix_Int(vector< vector<int> > ImgMatrix){ | |
for (int row_idx = 0; row_idx < ImgMatrix.size(); row_idx++){ | |
for (int col_idx = 0; col_idx < ImgMatrix[0].size(); col_idx++){ | |
cout << ImgMatrix[row_idx][col_idx] << " "; | |
} | |
cout << endl; | |
} | |
} | |
void Print_Matrix_Float(vector< vector<float> > ImgMatrix){ | |
for (int row_idx = 0; row_idx < ImgMatrix.size(); row_idx++){ | |
for (int col_idx = 0; col_idx < ImgMatrix[0].size(); col_idx++){ | |
cout << ImgMatrix[row_idx][col_idx] << " "; | |
} | |
cout << endl; | |
} | |
} | |
void Print_Vector_Int(vector<int> A){ | |
for (int idx = 0; idx < A.size(); idx ++){ | |
cout << A[idx] << " "; | |
} | |
} | |
void Print_Vector_Float(vector<float> A){ | |
for (int idx = 0; idx < A.size(); idx ++){ | |
cout << A[idx] << " "; | |
} | |
} | |
void Print_Histogram_Similarity(vector<float> X1_Prob, vector<float> X2_Prob){ | |
cout << "Correl (-1 to 1 (Good)) : " << compareHist(X1_Prob, X2_Prob, CV_COMP_CORREL) << endl; | |
cout << "Chi Square (0 best) : " << compareHist(X1_Prob, X2_Prob, CV_COMP_CHISQR) << endl; | |
cout << "Intersect (1 Best) : " << compareHist(X1_Prob, X2_Prob, CV_COMP_INTERSECT) << endl; | |
cout << "Bhattacharyya (0 Best) : " << compareHist(X1_Prob, X2_Prob, CV_COMP_BHATTACHARYYA) << endl; | |
} | |
void Two_Letter_Comparison(vector< vector<float> > X, vector< vector<float> > Y){ | |
vector<float> X_Xaxis = X[0]; | |
vector<float> X_Yaxis = X[1]; | |
vector<float> Y_Xaxis = Y[0]; | |
vector<float> Y_Yaxis = Y[1]; | |
cout << "---------- X-axis Comparison --------- " << endl; | |
cout << "Correl (-1 to 1 (Good)) : " << compareHist(X_Xaxis, Y_Xaxis, CV_COMP_CORREL) << endl; | |
cout << "Chi Square (0 best) : " << compareHist(X_Xaxis, Y_Xaxis, CV_COMP_CHISQR) << endl; | |
cout << "Intersect (1 Best) : " << compareHist(X_Xaxis, Y_Xaxis, CV_COMP_INTERSECT) << endl; | |
cout << "Bhattacharyya (0 Best) : " << compareHist(X_Xaxis, Y_Xaxis, CV_COMP_BHATTACHARYYA) << endl; | |
cout << endl; | |
cout << "---------- Y-axis Comparison --------- " << endl; | |
cout << "Correl (-1 to 1 (Good)) : " << compareHist(X_Yaxis, Y_Yaxis, CV_COMP_CORREL) << endl; | |
cout << "Chi Square (0 best) : " << compareHist(X_Yaxis, Y_Yaxis, CV_COMP_CHISQR) << endl; | |
cout << "Intersect (1 Best) : " << compareHist(X_Yaxis, Y_Yaxis, CV_COMP_INTERSECT) << endl; | |
cout << "Bhattacharyya (0 Best) : " << compareHist(X_Yaxis, Y_Yaxis, CV_COMP_BHATTACHARYYA) << endl; | |
} | |
/* ------------ Histogram Computation -------------- */ | |
vector< vector<int> > Histogram(vector< vector<int> > A){ | |
vector<int> X_axis; | |
vector<int> Y_axis; | |
vector< vector<int> > Hist; | |
int X_sum = 0; | |
int Y_sum = 0; | |
for (int row_idx = 0; row_idx < A.size(); row_idx ++){ | |
for (int col_idx = 0; col_idx < A[0].size(); col_idx ++){ | |
if (A[row_idx][col_idx] == 0){ | |
Y_sum += 1; | |
} | |
} | |
Y_axis.push_back(Y_sum); | |
Y_sum = 0; | |
} | |
for (int col_idx = 0; col_idx < A[0].size(); col_idx ++){ | |
for (int row_idx = 0; row_idx < A.size(); row_idx ++){ | |
if (A[row_idx][col_idx] == 0){ | |
X_sum += 1; | |
} | |
} | |
X_axis.push_back(X_sum); | |
X_sum = 0; | |
} | |
Hist.push_back(X_axis); | |
Hist.push_back(Y_axis); | |
return Hist; | |
} | |
vector<float> Probabilistic_Histogram(vector<int> A){ | |
int sum_val = 0; | |
vector<float> Prob_Hist; | |
for (int idx = 0; idx < A.size(); idx ++){ | |
sum_val += A[idx]; | |
} | |
for (int idx = 0; idx < A.size(); idx ++){ | |
Prob_Hist.push_back(float(A[idx] / float(sum_val))); | |
} | |
return Prob_Hist; | |
} | |
vector< vector< vector<float> > > Image_set_to_Point_set(vector<Mat> Cropped_Img_Set_A, int Img_Size, int Num_Img){ | |
vector< vector<int> > Image_Fixel(Mat ); | |
vector< vector<int> > Histogram(vector< vector<int> > ); | |
vector<int> Histogram_Smoothing_Reduction(vector<int> , int ); | |
vector<float> Probabilistic_Histogram(vector<int> ); | |
Mat Black_White(Mat ); | |
vector< vector<float> > Each_Image_Histogram_Matrix; | |
vector< vector< vector<float> > > Image_Histogram_Matrix_Set; | |
for (int idx =0 ; idx < Num_Img; idx ++){ | |
Each_Image_Histogram_Matrix.clear(); | |
Mat CroppedImg1 = Cropped_Img_Set_A[idx]; | |
Mat BW_Img1 = Black_White(CroppedImg1); | |
resize(BW_Img1, BW_Img1, Size(Img_Size, Img_Size)); | |
vector< vector<int> > Img_Fixel1 = Image_Fixel(BW_Img1); | |
vector< vector<int> > XY_Hist1 = Histogram(Img_Fixel1); | |
vector<int> X1_Hist = XY_Hist1[0]; | |
vector<int> Y1_Hist = XY_Hist1[1]; | |
// X1_Hist = Histogram_Smoothing_Reduction(X1_Hist,Reduction_Number); | |
// Y1_Hist = Histogram_Smoothing_Reduction(Y1_Hist,Reduction_Number); | |
vector<float> X1_Prob = Probabilistic_Histogram(X1_Hist); | |
vector<float> Y1_Prob = Probabilistic_Histogram(Y1_Hist); | |
// X1_Prob.insert( X1_Prob.end(), Y1_Prob.begin(), Y1_Prob.end() ); | |
Each_Image_Histogram_Matrix.push_back(X1_Prob); | |
Each_Image_Histogram_Matrix.push_back(Y1_Prob); | |
Image_Histogram_Matrix_Set.push_back(Each_Image_Histogram_Matrix); | |
} | |
return Image_Histogram_Matrix_Set; | |
} | |
vector<float> Representative_Value_for_each_cropped_img(vector< vector< vector<float> > > A_Train_Points, | |
vector< vector<float> > MY_test, int cut_num){ | |
vector<float> Intersect_VT_X; | |
vector<float> Intersect_VT_Y; | |
vector<float> Bat_VT_X; | |
vector<float> Bat_VT_Y; | |
vector<float> Result; | |
for (int idx = 0; idx < A_Train_Points.size(); idx++){ | |
vector< vector<float> > Each_Point = A_Train_Points[idx]; | |
vector<float> Each_Point_X = Each_Point[0]; | |
vector<float> Each_Point_Y = Each_Point[1]; | |
vector<float> MY_test_X = MY_test[0]; | |
vector<float> MY_test_Y = MY_test[1]; | |
// float COMP_COR_VAL_X = compareHist(Each_Point_X, MY_test_X, CV_COMP_CORREL); | |
// float COMP_CHI_VAL_X = compareHist(Each_Point_X, MY_test_X, CV_COMP_CHISQR); | |
float COMP_INT_VAL_X = compareHist(Each_Point_X, MY_test_X, CV_COMP_INTERSECT); | |
float COMP_BAT_VAL_X = compareHist(Each_Point_X, MY_test_X, CV_COMP_BHATTACHARYYA); | |
// float COMP_COR_VAL_Y = compareHist(Each_Point_Y, MY_test_Y, CV_COMP_CORREL); | |
// float COMP_CHI_VAL_Y = compareHist(Each_Point_Y, MY_test_Y, CV_COMP_CHISQR); | |
float COMP_INT_VAL_Y = compareHist(Each_Point_Y, MY_test_Y, CV_COMP_INTERSECT); | |
float COMP_BAT_VAL_Y = compareHist(Each_Point_Y, MY_test_Y, CV_COMP_BHATTACHARYYA); | |
// Correl_VT.push_back(COMP_COR_VAL); | |
// Chi_VT.push_back(COMP_CHI_VAL); | |
Intersect_VT_X.push_back(COMP_INT_VAL_X); | |
Bat_VT_X.push_back(COMP_BAT_VAL_X); | |
Intersect_VT_Y.push_back(COMP_INT_VAL_Y); | |
Bat_VT_Y.push_back(COMP_BAT_VAL_Y); | |
} | |
sort(Intersect_VT_X.begin(), Intersect_VT_X.end(), greater<float>()); | |
sort(Intersect_VT_Y.begin(), Intersect_VT_Y.end(), greater<float>()); | |
sort(Bat_VT_X.begin(), Bat_VT_X.end()); | |
sort(Bat_VT_Y.begin(), Bat_VT_Y.end()); | |
float Intersect_Sum_X = 0.0; | |
float Bat_Sum_X = 0.0; | |
float Intersect_Sum_Y = 0.0; | |
float Bat_Sum_Y = 0.0; | |
for (int idx = 0; idx < cut_num; idx ++){ | |
Intersect_Sum_X += Intersect_VT_X[idx]; | |
Bat_Sum_X += Bat_VT_X[idx]; | |
Intersect_Sum_Y += Intersect_VT_Y[idx]; | |
Bat_Sum_Y += Bat_VT_Y[idx]; | |
} | |
float Representative_Intersect_X = Intersect_Sum_X / cut_num; | |
float Representative_BAT_X = Bat_Sum_X / cut_num; | |
float Representative_Intersect_Y = Intersect_Sum_Y / cut_num; | |
float Representative_BAT_Y = Bat_Sum_Y / cut_num; | |
Result.push_back(Representative_Intersect_X); | |
Result.push_back(Representative_Intersect_Y); | |
Result.push_back(Representative_BAT_X); | |
Result.push_back(Representative_BAT_Y); | |
return Result; | |
} | |
vector< vector<float> > Representative_Value_for_Img(vector< vector< vector<float> > > A_Train_Points, | |
vector< vector< vector<float> > > A_Test_Points, int cut_num){ | |
vector<float> Representative_Value_for_each_cropped_img(vector< vector< vector<float> > > , | |
vector< vector<float> > , int ); | |
vector< vector<float> > Result_Matrix; | |
float temp_val; | |
for (int test_idx = 0; test_idx < A_Test_Points.size(); test_idx ++){ | |
vector< vector<float> > MY_test = A_Test_Points[test_idx]; | |
vector<float> Result_temp_vt = Representative_Value_for_each_cropped_img(A_Train_Points, MY_test, cut_num); | |
for (int temp_idx = 0; temp_idx < Result_temp_vt.size(); temp_idx ++){ | |
if (temp_idx <= 1){ | |
temp_val = Result_temp_vt[temp_idx]; | |
if (temp_val >= 0.8 && temp_val < 0.85){ | |
Result_temp_vt[temp_idx] *= 2; | |
} | |
else if (temp_val >= 0.85 && temp_val < 0.9){ | |
Result_temp_vt[temp_idx] *= 3; | |
} | |
else if (temp_val >= 0.9){ | |
Result_temp_vt[temp_idx] *= 4; | |
} | |
} | |
else if (temp_idx >= 2){ | |
temp_val = Result_temp_vt[temp_idx]; | |
if (temp_val >= 0.2 && temp_val < 0.25){ | |
Result_temp_vt[temp_idx] *= 2; | |
} | |
else if (temp_val >= 0.25 && temp_val < 0.3){ | |
Result_temp_vt[temp_idx] *= 3; | |
} | |
else if (temp_val > 0.3){ | |
Result_temp_vt[temp_idx] *= 4; | |
} | |
} | |
} | |
Result_Matrix.push_back(Result_temp_vt); | |
} | |
return Result_Matrix; | |
} | |
float Representative_Value_Computation(vector< vector<float> > Result_Matrix, | |
float weight_intersect_x, float weight_intersect_y, float weight_bat_x, float weight_bat_y){ | |
float intersect_x_sum = 0.0; | |
float intersect_y_sum = 0.0; | |
float bat_x_sum = 0.0; | |
float bat_y_sum = 0.0; | |
float result_val; | |
int row_num = Result_Matrix.size(); | |
vector<float> Temp_Vector; | |
for (int row_idx = 0; row_idx < Result_Matrix.size(); row_idx ++){ | |
Temp_Vector = Result_Matrix[row_idx]; | |
intersect_x_sum += Temp_Vector[0]; | |
intersect_y_sum += Temp_Vector[1]; | |
bat_x_sum += Temp_Vector[2]; | |
bat_y_sum += Temp_Vector[3]; | |
} | |
intersect_x_sum /= row_num; | |
intersect_y_sum /= row_num; | |
bat_x_sum /= row_num; | |
bat_y_sum /= row_num; | |
result_val = weight_intersect_x * intersect_x_sum + weight_intersect_y * intersect_y_sum + | |
weight_bat_x * bat_x_sum + weight_bat_y * bat_y_sum; | |
return result_val; | |
} | |
int main(int argc,char** argv){ | |
/* --------------------- Control variables ------------------*/ | |
int Img_Idx1, Img_Idx2; | |
int lowThreshold = 10; | |
int const max_lowThreshold = 100; | |
int ratio = 30; | |
int kernel_size = 3; | |
int Reduction_Number = 50; | |
int Train_Num_Img = 15; | |
int Test_Num_Img = 5; | |
int K = 7; | |
int Img_Size = 100; | |
int cut_num = 5; | |
vector< vector< vector<float> > > Train_Points; | |
vector< vector< vector<float> > > Test_Points; | |
/* ------------------ Construct the image point -------------- */ | |
string A_Train_Path = "DATA_PA/character_data001.bmp"; | |
string B_Train_Path = "DATA_PA/character_data002.bmp"; | |
string C_Train_Path = "DATA_PA/character_data003.bmp"; | |
string D_Train_Path = "DATA_PA/character_data004.bmp"; | |
string E_Train_Path = "DATA_PA/character_data005.bmp"; | |
string Test_Path = "DATA_PA/CharE.bmp"; | |
// string A_Test_Path = "DATA_PA/CharA.bmp"; | |
// string B_Test_Path = "DATA_PA/CharB.bmp"; | |
// string C_Test_Path = "DATA_PA/CharC.bmp"; | |
// string D_Test_Path = "DATA_PA/CharD.bmp"; | |
// string E_Test_Path = "DATA_PA/CharE.bmp"; | |
vector<Mat>A_Train_Cropped = Cropped_Vector_Construction(A_Train_Path, Train_Num_Img); | |
vector<Mat>B_Train_Cropped = Cropped_Vector_Construction(B_Train_Path, Train_Num_Img); | |
vector<Mat>C_Train_Cropped = Cropped_Vector_Construction(C_Train_Path, Train_Num_Img); | |
vector<Mat>D_Train_Cropped = Cropped_Vector_Construction(D_Train_Path, Train_Num_Img); | |
vector<Mat>E_Train_Cropped = Cropped_Vector_Construction(E_Train_Path, Train_Num_Img); | |
vector<Mat>Test_Cropped = Cropped_Vector_Construction(Test_Path, Test_Num_Img); | |
// ---------- Convert Training Cropped Image Vector to the High dim point ----------- | |
vector< vector< vector<float> > > A_Train_Points = Image_set_to_Point_set(A_Train_Cropped, Img_Size, Train_Num_Img); | |
vector< vector< vector<float> > > B_Train_Points = Image_set_to_Point_set(B_Train_Cropped, Img_Size, Train_Num_Img); | |
vector< vector< vector<float> > > C_Train_Points = Image_set_to_Point_set(C_Train_Cropped, Img_Size, Train_Num_Img); | |
vector< vector< vector<float> > > D_Train_Points = Image_set_to_Point_set(D_Train_Cropped, Img_Size, Train_Num_Img); | |
vector< vector< vector<float> > > E_Train_Points = Image_set_to_Point_set(E_Train_Cropped, Img_Size, Train_Num_Img); | |
Test_Points = Image_set_to_Point_set(Test_Cropped, Img_Size, Test_Num_Img); | |
/* --------------- Comparison with all Training points, and get the Five max AVG as the representative measure ------------ */ | |
vector< vector<float> > A_Representative_Matrix = Representative_Value_for_Img(A_Train_Points, Test_Points, cut_num); | |
vector< vector<float> > B_Representative_Matrix = Representative_Value_for_Img(B_Train_Points, Test_Points, cut_num); | |
vector< vector<float> > C_Representative_Matrix = Representative_Value_for_Img(C_Train_Points, Test_Points, cut_num); | |
vector< vector<float> > D_Representative_Matrix = Representative_Value_for_Img(D_Train_Points, Test_Points, cut_num); | |
vector< vector<float> > E_Representative_Matrix = Representative_Value_for_Img(E_Train_Points, Test_Points, cut_num); | |
float A_Value = Representative_Value_Computation(A_Representative_Matrix, 1,1,-1,-1); | |
float B_Value = Representative_Value_Computation(B_Representative_Matrix, 1,1,-1,-1); | |
float C_Value = Representative_Value_Computation(C_Representative_Matrix, 1,1,-1,-1); | |
float D_Value = Representative_Value_Computation(D_Representative_Matrix, 1,1,-1,-1); | |
float E_Value = Representative_Value_Computation(E_Representative_Matrix, 1,1,-1,-1); | |
vector<float> Representative_Value; | |
Representative_Value.push_back(A_Value); | |
Representative_Value.push_back(B_Value); | |
Representative_Value.push_back(C_Value); | |
Representative_Value.push_back(D_Value); | |
Representative_Value.push_back(E_Value); | |
if (A_Value == *max_element(Representative_Value.begin(), Representative_Value.end())){ | |
cout << "Test Image : A" << endl; | |
} | |
else if (B_Value == *max_element(Representative_Value.begin(), Representative_Value.end())){ | |
cout << "Test Image : B" << endl; | |
} | |
else if (C_Value == *max_element(Representative_Value.begin(), Representative_Value.end())){ | |
cout << "Test Image : C" << endl; | |
} | |
else if (D_Value == *max_element(Representative_Value.begin(), Representative_Value.end())){ | |
cout << "Test Image : D" << endl; | |
} | |
else if (E_Value == *max_element(Representative_Value.begin(), Representative_Value.end())){ | |
cout << "Test Image : E" << endl; | |
} | |
cout << endl; | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment