车牌号图像的垂直投影
摘要:图像对应方向的投影,就是在该方向取一条直线,统计垂直于该直线(轴)的图像上的像素的黑点数量,累加求和作为该轴该位置的值;基于图像投影的切割就是将图像映射成这种特征后,基于这种特征判定图像的切割位置(坐标),用这个坐标来切割原图像,得到目标图像。即可垂直投影的特点对车牌号进行切割。
(1)垂直投影
vector<Mat> verticalProjectionMat(Mat Image)
{
int perPixelValue;//每个像素的值
int width = Image.cols;
int height = Image.rows;
printf("图片的宽%d图片的高%d", width, height);
int* projectValArry = new int[width];//创建用于储存每列白色像素个数的数组
memset(projectValArry, 0, width * 4);//初始化数组
for (int col = 0; col < width; col++)//列
{
for (int row = 0; row < height; row++)//行
{
perPixelValue = Image.at<uchar>(row, col);//每个像素的值
if (perPixelValue == 255)//黑底白字 if (perPixelValue == 0)//白底黑字 】
{
projectValArry[col]++;//列的叠加
}
}
}
(2)垂直投影的画布
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
perPixelValue = 255; //背景设置为白色
verticalProjectionMat.at<uchar>(i, j) = perPixelValue;
}
}
for (int i = 0; i < width; i++)//垂直投影直方图
{
for (int j = 0; j < projectValArry[i]; j++)
{
perPixelValue = 0; //直方图设置为黑色
verticalProjectionMat.at<uchar>(height - 1 - j, i) = perPixelValue;
}
}
imshow("垂直投影", verticalProjectionMat);
Rect rect(0, 0, 356, 90);
Mat image_cut = Mat(verticalProjectionMat, rect);
Mat image_copy = image_cut.clone();
imshow("切割图片", image_copy);
(3)遍历图片区域
vector<Mat> roiList;//用于储存分割出来的每个字符int startIndex = 0;//记录进入字符区的索引
int endIndex = 0;//记录进入空白区域的索引
bool inBlock = false;//是否遍历到了字符区内
for (int i = 0; i < Image.cols; i++)//cols=width
{
if (!inBlock && projectValArry[i] != 0)//进入字符区
{
inBlock = true;
startIndex = i;
}
else if (projectValArry[i] == 0 && inBlock)//进入空白区
{
endIndex = i;
inBlock = false;
Mat roiImg = Image(Range(0, Image.rows), Range(startIndex, endIndex + 1));
roiList.push_back(roiImg);
}
}
delete[] projectValArry;
return roiList;
}
(4)图片的读取和显示结果
参考文献:垂直投影__百度百科
基于垂直投影的车牌字符分割方法 https://wenku.baidu.com/view/23c05e2df78a6529647d5364