日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用OpenCV的ANN_MLP神经网络实现数字识别

發(fā)布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用OpenCV的ANN_MLP神经网络实现数字识别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

1.OpenCV中的ML模塊實現(xiàn)了前饋人工神經(jīng)網(wǎng)絡,具體地說是多層感知器(MLP),是最常用的神經(jīng)網(wǎng)絡類型。 MLP由輸入層,輸出層和一個或多個隱藏層組成。 MLP的每一層包括一個或多個與來自上一層和下一層的神經(jīng)元定向連接的神經(jīng)元。關(guān)于ANN_MLP的具體說明可以看opencv的官方文檔。
2.我這里要是使用ANN_MLP神經(jīng)網(wǎng)絡來實現(xiàn)0到9的印刷數(shù)字識別,使用的OpenCV版本是3.30,IDE是VS2015,實現(xiàn)語言是C++,還使用了boost來進行文件讀取的相關(guān)操作。

樣本準備

1.先準備0到9的樣本,分別放在相應的文件目錄下,這是我保存的格式:

2.每個目錄下放著對的樣本,我這里每個字母都有50個樣本,對應的文件沒有特殊要求。

代碼

1.訓練代碼

//訓練函數(shù) //root_path樣本地址 //model_path保存模型路徑加文件名,后續(xù)為xml void trainChar(string &root_path, string &model_path) {vector<string> dir_path;int dir_number;getFileNameFromDir(root_path, dir_path, dir_number);//圖像的行const int image_rows = 8;//圖像的列const int image_cols = 16;//要訓練的類別const int class_sum = 10;//每個類別的樣本個數(shù)const int images_sum = 50;if (dir_number != class_sum){cout << "要訓練的種類與當前目錄下的種類和差異!" << endl;return;}//每一行一個訓練樣本float trainingData[class_sum*images_sum][image_rows*image_cols] = { { 0 } };//訓練樣本標簽float labels[class_sum*images_sum][class_sum] = { { 0 } };Mat src, resize_img, train_img;//這里讀文件的方式不是很好,用boost會好一些for (int i = 0; i < dir_path.size(); i++){//cout << dir_path.at(i) << endl;int k = 0;fs::directory_iterator begin_iter(dir_path.at(i));fs::directory_iterator end_iter;//獲取該目錄下的所有文件名for (; begin_iter != end_iter; ++begin_iter){string image_path = begin_iter->path().string();src = imread(image_path, 0);if (src.empty()){cerr << "can not load image \n" << std::endl;exit(0);}//更改尺寸resize(src, resize_img, Size(image_rows, image_cols), (0, 0), (0, 0), INTER_AREA);//二值化threshold(resize_img, train_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);for (int j = 0; j < image_rows*image_cols; j++){trainingData[i*images_sum + k][j] = (float)resize_img.data[j];}// 設置標簽數(shù)據(jù)for (int j = 0; j < class_sum; j++){if (j == i){labels[i*images_sum + k][j] = 1;}else{labels[i*images_sum + k][j] = 0;}}k++;}Mat labelsMat(class_sum*images_sum, class_sum, CV_32FC1, labels);}//訓練數(shù)據(jù)及標簽Mat trainingDataMat(class_sum*images_sum, image_rows*image_cols, CV_32FC1, trainingData);Mat labelsMat(class_sum*images_sum, class_sum, CV_32FC1, labels);//設置參數(shù)Ptr<ANN_MLP>model = ANN_MLP::create();Mat layerSizes = (Mat_<int>(1, 5) << image_rows*image_cols, 128, 128, 128, class_sum);model->setLayerSizes(layerSizes);//訓練方法為反向傳播(這個跟深度學習的反向轉(zhuǎn)播是一個道理)model->setTrainMethod(ANN_MLP::BACKPROP, 0.001, 0.1);// 激活函數(shù)設置為 sigmoidmodel->setActivationFunction(ANN_MLP::SIGMOID_SYM, 1.0, 1.0);model->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS, 10000, 0.0001));cout << "開始訓練!" << endl;Ptr<TrainData> trainData = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);model->train(trainData);//保存模型model->save(model_path);cout << "訓練完成" << endl; }//得到路徑下第一層的文件夾的絕對路徑 void getFileNameFromDir(string &root_path,vector<string> &dir_path, int &class_sum) {class_sum = 0;vector<string> dir_name;fs::path dir(root_path);// 判斷路徑是否存在if (fs::exists(dir)){fs::directory_iterator itEnd;fs::directory_iterator itDir(dir);string file_name;// 遍歷路徑下所有文件for (; itDir != itEnd; itDir++){file_name = itDir->path().string();// 判斷文件是否是文件夾if (boost::filesystem::is_directory(file_name.c_str())){dir_path.push_back(file_name);class_sum++; }}} }

訓練代碼調(diào)用方式:

//保存字符集的主目錄 string char_path = "C:/code/DigitalRecognition/DigitalRecognition/numberChar/"; //訓練好的模型保存的路徑和文件名 string model_path = "C:/code/DigitalRecognition/DigitalRecognition/numberCharModel.xml"; trainChar(char_path,model_path);

2.測試代碼

//測試模型 //src是要識別的圖像 //model_path模型的路徑 void useModel(Mat &src, string &model_path) {if (src.empty()){cout << "當前傳入的圖像為空!" << endl;return;}if (src.channels() > 1){cvtColor(src, src, CV_BGR2GRAY);}Mat dst;//圖像的行const int image_rows = 8;//圖像的列const int image_cols = 16;Ptr<ANN_MLP>model = ANN_MLP::create();model = cv::Algorithm::load<cv::ml::ANN_MLP>(model_path);//將測試圖像轉(zhuǎn)化為1*128的向量resize(src, src, Size(image_rows, image_cols), (0, 0), (0, 0), INTER_AREA);threshold(src, src, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);Mat_<float> testMat(1, image_rows*image_cols);for (int i = 0; i < image_rows*image_cols; i++){testMat.at<float>(0, i) = (float)src.at<uchar>(i / 8, i % 8);}//使用訓練好的MLP model預測測試圖像,把預測到的值放到dst里面model->predict(testMat, dst);cout << "dst:" << dst << endl;//選出最大值double maxVal = 0;Point maxLoc;minMaxLoc(dst, NULL, &maxVal, NULL, &maxLoc);cout << "測試結(jié)果:" << maxLoc.x << "置信度:" << maxVal * 100 << "%" << endl; }

測試代碼調(diào)用方式:

//訓練好的模型保存的路徑和文件名 string model_path = "C:/code/DigitalRecognition/DigitalRecognition/numberCharModel.xml"; //讀取圖像 Mat src = imread("src.png"); useModel(src,model_path);

運行結(jié)果:

結(jié)語

1.上面的所用到的樣本,可以從我的資源上傳那里得到。
2.如果在運行中有什么bug,可以找我之前的博客,下面有推薦的群,互相討論學習。

總結(jié)

以上是生活随笔為你收集整理的使用OpenCV的ANN_MLP神经网络实现数字识别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。