opencv进行车牌提取,数字为水平方向

原车牌图片:

——————————————————————————————————————————————————————————-——————

二值化后图片

——————————————————————————————————————————————————————————————————

沿竖直方向投影,得出白色像素的数目

————————————————————————————————————————————————————————————

最终分割结果

————————————————————————————————————————————————————————

/*绝大部分代码是借鉴转载的,出处忘记了,只是为了自己学习记录*/

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<iostream>
#include <stdio.h>
using namespace std;
using namespace cv;

Mat vertical_projection(Mat input_src) //输入二值化图片
{ /**************统计原图片中每列白色像素数目******************************/ 
blur(input_src, input_src, Size(3, 3));//模糊,去锯齿 
int src_width = input_src.cols; 
int src_height = input_src.rows; 
int* projectValArry = new int[src_width]();//创建用于储存每列白色像素个数的数组 
//memset(projectValArry, 0, src_width*4);//初始化数组 
//取列白色像素个数 
for (int i = 0; i < src_height; i++){  
 for (int j = 0; j < src_width; j++){   
  if (input_src.at<uchar>(i, j)){    
   projectValArry[j]++;       // projectValArry[1]代表第一列的数值 
  }  
 } 
} /**************将每列白色像素数目绘制成直方图***************************/ 
 //定义画布 绘制垂直投影下每列白色像素的数目 
Mat verticalProjectionMat(src_height, src_width, CV_8UC1, Scalar(0)); 
for (int i = 0; i< src_width; i++){  
 for (int j = 0; j < projectValArry[i]; j++){       //projectValArry[i]为每列中的白色像素  
  verticalProjectionMat.at<uchar>(src_height - j - 1,i) = 255; //src_height-j-1 
 } 

imshow("verticalProjectionMat", verticalProjectionMat);  
/*********根据每列白色像素数目设置截取起始和截止列***********************/ 
//定义Mat vector ,存储图片组 
vector<Mat> split_src; //定义标志,用来指示在白色像素区还是在全黑区域 
bool white_block = 0, black_block = 0; 
//定义列temp_col_forword  temp_col_behind,记录字符截取起始列和截止列 
int temp_col_forword=0,temp_col_behind = 0; Mat split_temp; 
//遍历数组projectValArry 
for (int i = 0; i < src_width; i++){  
 if (projectValArry[i]){//表示区域有白色像素   
  white_block = 1;   
  black_block = 0;  }  
 else{    //若无白色像素(进入黑色区域)   
  if (white_block == 1){//若前一列有白色像素    
   temp_col_behind = i;//取当前列为截止列    //截取下一部分    //input_src(Rect(temp_col_forword, 0, temp_col_behind - temp_col_forword, src_height)).copyTo(split_temp);                //2019-4-25 更新: 使用.copyTo()会出现丢字符的情况,建议使用.clone()                //感谢网友“a路小雨”测试提出宝贵意见               
   split_temp=input_src(Rect(temp_col_forword, 0, temp_col_behind - temp_col_forword, src_height)).clone();   //左上角为起始点    
   split_src.push_back(split_temp);   }   
  temp_col_forword = i;//记录最新黑色区域的列号,记为起始列   
  black_block = 1;//表示进入黑色区域   
  white_block = 0;  
 } 

for (int i = 0; i < split_src.size(); i++){  
 char window[20];  
 sprintf(window, " split: %d", i);  
 imshow(window, split_src[i]); 

waitKey(0); 
return input_src;}

int main(){  
 Mat srcImage = imread("F:\\LiuHuan_File\\tupian\\chepai.png");  
 if (!srcImage.data)
 {cout << "failed to read" << endl;   
 system("pause");   
 return -1;  
 }  
 Mat srcGray;  
 cvtColor(srcImage, srcGray, CV_BGR2GRAY);  
 Mat bin_src;  
 threshold(srcGray, bin_src, 100, 255, CV_THRESH_OTSU); //otsu二值化图像  
 imshow("bin_src", bin_src);  
 vertical_projection(bin_src);  
 waitKey(0);  
 return 0;}

猜你喜欢

转载自www.cnblogs.com/liutangzhu/p/11952843.html