opencv车牌提取,沿水平方向提取

以下分别是原车牌,二值化,水平投影的结果,最终分割结果

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

/*在其他人代码基础上修改的,非原创*/

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace cv;
using namespace std;

Mat horizontal_projection(Mat input_src);

int main() {
 Mat srcImage = imread("F:\\LiuHuan_File\\tupian\\chepai3.png");
 imshow("原车牌图片", srcImage);
 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);
 horizontal_projection(bin_src);
 waitKey(0);
 return 0;
}
Mat horizontal_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_height]();//创建用于储存每行白色像素个数的数组 
              //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[i]++;
   }
  }
 } /**************将每行白色像素数目绘制成直方图***************************/
  //定义画布 绘制垂直投影下每行白色像素的数目 
 Mat horizontalProjectionMat(src_height, src_width, CV_8UC1, Scalar(0));
 for (int i = 0; i< src_height; i++) {
  for (int j = 0; j < projectValArry[i]; j++) {
   horizontalProjectionMat.at<uchar>(i,src_width - j - 1) = 255; //src_height-j-1 
  }
 }
 imshow("horizontalProjectionMat", horizontalProjectionMat);
 /*********根据每行白色像素数目设置截取起始和截止列***********************/
 //定义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_height; 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(0, temp_col_forword, src_width, temp_col_behind - temp_col_forword)).clone();   //(x,y)左上角
    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]);
 }
 return input_src;
}

 

 

 

posted @ 2019-11-28 19:06  刘书虫100  阅读(237)  评论(0)    收藏  举报