91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

opencv怎么實現簡單的數字識別

發布時間:2021-09-09 13:45:52 來源:億速云 閱讀:195 作者:chen 欄目:開發技術

這篇文章主要介紹“opencv怎么實現簡單的數字識別”,在日常操作中,相信很多人在opencv怎么實現簡單的數字識別問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”opencv怎么實現簡單的數字識別”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目錄
  • 前言

  • 要解決的問題

  • 解決問題的思路


前言

由于自己學識尚淺,不能用python深度學習來識別這里的數字,所以就完全采用opencv來識別數字,然后在這里分享、記錄一下自己在學習過程中的一些所見所得和所想

要解決的問題

這是一個要識別的數字,我這里首先是對圖像進行一個ROI的提取,提取結果就僅僅剩下數字,把其他的一些無關緊要的要素排除在外,

opencv怎么實現簡單的數字識別

這是ROI圖片,我們要做的就是識別出該照片中的數字,

解決問題的思路

1、先把這個圖片中的數字分割,分割成為5張小圖片,每張圖片包含一個數字,為啥要分割呢?因為我們沒辦法讓計算機知道這個數字是多少,所以只能根據特征,讓計算機去識別特征,然后每一個特征對應一個值,首先貼出分割圖片的程序,然后在程序下方會有一段思路解釋

#include <opencv2/core/core.hpp>
#include <opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <ctime>
using namespace std ;
using namespace cv;
#include <map>
Mat src_threshold;
Mat src_dil;
int sunImage(Mat &image);
vector<Mat>ROI_image;//待測圖片
int main() 
{
	clock_t start ,finish;
	start=clock();
	Mat src;
	src=imread("D:\\vspic\\picture\\number6.jpg");
	resize(src,src,Size(src.cols/7,src.rows/7));
	imshow("src",src);
	Mat src_gray;
	cvtColor(src,src_gray,COLOR_BGR2GRAY);
	//imshow("gsrc_ray",src_gray);
	Mat src_blur;
	blur(src_gray,src_blur,Size(9,9));
	//GaussianBlur(src_gray,src_blur,Size(11,11),1,1);
	Mat src_threshold;
	threshold(src_blur,src_threshold,150,255,THRESH_OTSU);
	//imshow("src_threshold",src_threshold);
	Mat src_canny;
	Canny(src_threshold,src_canny,125,255,3);
	//imshow("src_canny",src_canny);
	vector<vector<Point>>contours_src;
	vector<Vec4i>hierarchy_src(contours_src.size());
	findContours(src_canny,contours_src,hierarchy_src,RETR_EXTERNAL,CHAIN_APPROX_NONE);
	Rect rect_s;
	Rect choose_rect;
	for (size_t i=0;i<contours_src.size();i++)
	{
		rect_s=boundingRect(contours_src[i]);
		double width=rect_s.width;
		double height= rect_s.height;
		double bizhi=width/height;
		if (bizhi>1.5&&height>50)
		{
			/*rectangle(src,rect_s.tl(),rect_s.br(),Scalar(255,255,255),1,1,0);*/
			choose_rect=Rect(rect_s.x+20,rect_s.y+30,rect_s.x-30,rect_s.y-108);
		}
	}
	Mat roi;
	roi=src(choose_rect);
	//imshow("src_",roi);
	Mat img =roi;
	Mat gray_img;
	// 生成灰度圖像
	cvtColor(img, gray_img, CV_BGR2GRAY);
	// 高斯模糊
	Mat img_gau;
	GaussianBlur(gray_img, img_gau, Size(3, 3), 0, 0);
	// 閾值分割
	Mat img_seg;
	threshold(img_gau, img_seg, 0, 255, THRESH_BINARY + THRESH_OTSU);
	Mat element;
	element=getStructuringElement(MORPH_RECT,Size(8,8));
	erode(img_seg,src_dil,element);
	//imshow("src_dil",src_dil);
	// 邊緣檢測,提取輪廓
	Mat img_canny;
	Canny(src_dil, img_canny, 200, 100);
	//imshow("canny",img_canny);
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy(contours.size());
	findContours(img_canny, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point());//尋找輪廓
	int size = (int)(contours.size());//輪廓的數量
	//cout<<size<<endl;6個
	// 保存符號邊框的序號
	vector<int> num_order;//定義一個整型int容器
	map<int, int> num_map;//容器,需要關鍵字和模板對象兩個模板參數,此處定義一個int作為索引,并擁有相關連的指向int的指針
	for (int i = 0; i < size; i++)
   {
		// 獲取邊框數據
		Rect number_rect = boundingRect(contours[i]);
		int width = number_rect.width;//獲取矩形的寬
		int height = number_rect.height;//獲取矩形的高
		// 去除較小的干擾邊框,篩選出合適的區域
		if (width > img.cols/20 )
		{
			rectangle(img,number_rect.tl(),number_rect.br(),Scalar(255,255,255),1,1,0);//繪制矩形
			imshow("img",img);//顯示矩形框
			num_order.push_back(number_rect.x);//把矩形的x坐標放入number_order容器中,將一個新的元素添加到vector的最后面,
			//位置為當前元素的下一個元素
			num_map[number_rect.x] = i;//向map中存入鍵值對,number_rect.x是關鍵字,i是值
			/*把矩形框的x坐標與對應的i值一起放入map容器中,形成一一對應的鍵值對
			*/
		}
	}
	// 按符號順序提取
	sort(num_order.begin(), num_order.end());/*把number_order容器中的內容按照從小到大的順序排列,這里面是X的坐標*/
	for (int i = 0; i < num_order.size(); i++) {
		Rect number_rect = boundingRect(contours[num_map.find(num_order[i])->second]);//num_order里面放的是坐標
		//cout<<"num_map的值是:"<<num_map.find(num_order[i])->second<<endl;
		Rect choose_rect(number_rect.x, 0, number_rect.width, img.rows);//矩形左上角x,y的坐標以及矩形的寬和高
		Mat number_img = img(choose_rect);
		resize(number_img,number_img,Size(30,100));//歸一化尺寸
		ROI_image.push_back(number_img);//保存為待測圖片
		//imshow("number" + to_string(i), number_img);
		char name[50];
		sprintf_s(name,"D:\\vs2012\\model\\%d.jpg",i);//保存模板
		imwrite(name, number_img);	
	}
	cout<<"圖片分割完畢"<<endl;
	//加載模板
	vector<Mat>temptImage;//存放模板
	for (int i=0;i<4;i++)
	{
		char name[50];
		sprintf_s(name,"D:\\vs2012\\model\\%d.jpg",i);
		Mat temp;
		temp=imread(name);
		//cout<<"加載模板圖片通道數:"<<temp.channels()<<endl;
		temptImage.push_back(temp);
	}
	vector<int>seq;//存放順序結果
	for (int i=0;i<ROI_image.size();i++)
	{
		Mat subImage;
		int sum=0;
		int min=50000;
		int seq_min=0;//記錄最小的和對應的數字
		for (int j=0;j<4;j++)
		{
			absdiff(ROI_image[i],temptImage[j],subImage);//待測圖片像素減去模板圖片像素
			sum=sunImage(subImage);//統計像素和
			if (sum<min)
			{
				min=sum;
			    seq_min=j;
			}
			sum=0;
		}
		seq.push_back(seq_min);
	}
	cout<<"輸出數字匹配結果:";//endl是換行的意思
	for (int i=0;i<seq.size();i++)//輸出結果,小數點固定在第3位
	{
		cout<<seq[i];
		if (i==1)
		{
			cout<<".";
		}
	}
	finish=clock();
	double all_time=double(finish-start)/CLOCKS_PER_SEC;
	/*cout<<"運行總時間是:"<<all_time<<endl;*/
	waitKey(0);
	return 0;
}
//計算像素和
int sunImage(Mat &image)
{
	int sum=0;
	for (int i=0;i<image.cols;i++)
	{
		for (int j=0;j<image.rows;j++)
		{
			sum+=image.at<uchar>(j,i);
		}
	}
	return sum;
}

整體思路是這樣子的:0-9這10個數字也都是已經被分割好的,并且保存好了,也就是模板,然后我們把待測的圖片也分割掉,然后從0-9模板文件夾中去讀取模板圖片,讓待測的分割完畢的圖片去和10個模板逐個相減,然后去統計他們相減后的像素和,如果這個在這10個中最低,那么他們就是同一個數字,然后輸出值就可以了,分割后的大概是這樣

opencv怎么實現簡單的數字識別

上邊是第一種方法,然后還有第二種,是穿針引線的方法,是根據晶體管數字特征來識別的

opencv怎么實現簡單的數字識別

這是晶體管數字的特征,每個0-9每個數字都是不一樣的,我們下一篇文章再做詳細的介紹

到此,關于“opencv怎么實現簡單的數字識別”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

珠海市| 红河县| 奉节县| 逊克县| 获嘉县| 华阴市| 赤水市| 象州县| 浙江省| 连云港市| 天台县| 珠海市| 灵璧县| 永清县| 清镇市| 淮北市| 赤峰市| 德钦县| 抚远县| 绵阳市| 青阳县| 江门市| 南澳县| 三都| 江源县| 三亚市| 页游| 当涂县| 彰武县| 姜堰市| 漳浦县| 鹤岗市| 清水河县| 东阳市| 讷河市| 彭泽县| 南平市| 宝山区| 定兴县| 怀柔区| 永康市|