杭电4 License Plate Recognition 降维映射

原题链接;https://acm.hdu.edu.cn/showproblem.php?pid=6993

Little Rabbit is a college student who is studying Communication Engineering. In this term, he has a course called Digital Image Processing. At the end of the course, Little Rabbit needs to complete a project called License Plate Recognition, in which Little Rabbit should program a system to recognize the characters of a license plate in an image.

A classic License Plate Recognition system has three modules:
  • License Plate Localization: to localize the license plate in the image.
  • Character Segmentation: to segment the image so that the characters of the license plate can be separated.
  • Character Recognition: to recognize the characters in the image and get the result string.
To complete the project, Little Rabbit builds a team of three members. Each member is in charge of one module. Here, Little Rabbit is in charge of the second module --- Character Segmentation.

After the License Plate Localization module and some preprocessing, Little Rabbit gets some binary images that represent the license plates. The binary images are all 100 pixels in width and 30 pixels in height, containing only black pixels and white pixels. The black pixels represent the background, and the white pixels represent the characters.

Little Rabbit's task is to segment the binary images so that the characters in the images can be separated. According to the standard, there are seven characters in a license plate, lining up from left to right. Specifically, Little Rabbit's task is to find the left boundary and the right boundary of each character.

Let's consider the images as matrices with 30 rows and 100 columns. Then number the columns 1 to 100 from left to right. We define the left boundary of a character as the index of the column where the leftmost pixel is located, and the right boundary as the index of the column where the rightmost pixel is located. For example, in the following picture, the left boundary of the character is 3, and the right boundary is 7.
 



Now given the binary images that Little Rabbit needs to segment, please output the left boundary and the right boundary of each character. In this problem, we use . to represent a black pixel, and # to represent a white pixel.

Input
The first line contains an integer T (1≤ T≤50) --- the number of test cases.

Each test case represents a binary image, which contains 30 lines of strings. Each line contains 100 characters, either . (a black pixel) or # (a white pixel).

Here are all the characters that may appear in the image.

Chinese characters:
 



ASCII version: https://paste.ubuntu.com/p/B5pTWv7s6J/
(Backup: https://github.com/cjj490168650/plate/blob/main/chn.txt)

English and numeric characters:
 



ASCII version: https://paste.ubuntu.com/p/59bjvwY3Yr/
(Backup: https://github.com/cjj490168650/plate/blob/main/eng.txt)

It is guaranteed that:
  • The characters in the image follow the standard of license plates. There are seven characters in the image, lining up from left to right. The first character is a Chinese character. The second character is an English character. The last five characters are English or numeric characters.
  • All characters in the image are identical to the characters given above (ASCII version), including the size and the shape.
  • There are no redundant white pixels in the image.
  • There is spacing between characters.
  • The characters won't touch or get out of the image boundaries.

Output
For the x-th test case, output Case #x: in the first line.

Then in the next seven lines, the i-th line contains two integers separated by a space character, indicating the left boundary and the right boundary of the i-th character.

Sample Input
 
 
1 .................................................................................................... .................................................................................................... .................................................................................................... .................................................................................................... .................................................................................................... .................................................................................................... .................................................................................................... ..........................##...........##..........#####......########..........##......########.... .......#.......#..........###..........##.........#######.....########.........###......########.... .......#.......#..........###..........##........##....##..........###.........###......##.......... .......#.......#.........####..........##...............##........###.........####......##.......... ....###############......####..........##..............##........###..........####......##.......... .......#.......#.........##.#..........##..............##.......###...........####......##.......... .......#.......#.........##.##.........##..............##.......#####........#####......#######..... .......#.......#.........##.##.........##.............##........######.......##.##......########.... .......#.......#........###.##.........##............###............##......###.##............###... .......#########........##..##.........##...........###.............##......##..##.............##... .......#.......#........##...#.........##...........##..............##......##..##.............##... .......#.......#........##...##........##..........###..............##.....##...##.............##... .......#.......#........#######........##.........###.........##....##.....#########...........##... .......#.......#.......########........##.........##..........##....##.....#########....##.....##... .......#########.......##....##........##........###..........###...##..........##.......##...###... .......#.......#.......##....##........##........########......######...........##.......#######.... .......................##.....##.......##........########.......####............##........#####..... .................................................................................................... .................................................................................................... .................................................................................................... .................................................................................................... .................................................................................................... ....................................................................................................

Sample Output
 
 
Case #1:
5 19
24 32
40 41
50 58
63 70
76 84
89 97
思路: 将所有的"#"映射到一维坐标上,是'#'就将对应列数映射为1。
 由于车牌号是由一个汉字+一个字母+五个数字组成的。字母和数字都是都是连续的,而汉字存在“川”这种中间出现间断的情况。
所以我们从后往前遍历,先将数字、字母的左右边界和汉字的右边界加入小根堆(堆顶元素最小,自动排序),再从前往后遍历,将汉字的左边界加入小根堆。
最后再按格式挨个输出就好。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int t;
int main(){
	cin>>t;
	for(int k=1;k<=t;k++){
		priority_queue<int,vector<int>,greater<int> > q;//小根堆 
	  map<int,int> mp;//将'#' 与列号建立映射关系 
	  bool vis[100]={false};
	  for(int i=1;i<=30;i++){
	     for(int j=1;j<=100;j++){
	     	char c;
	     	cin>>c;
	     	if(c=='#'&&!vis[j]){
	     		mp[j]=1;//如果是'#',就将列号j映射为1 
	     		vis[j]=true;//注意只有c=='#'时才能将vis[j]=true,因为其他行是'#'时是可以覆盖原来的0的 
			 }
			 else if(c!='#'&&!vis[j]){
			 	mp[j]=0;//其他标记为0 
			 }
		 } 
	  }
	  for(int i=1;i<=100;i++){
	  	if(mp[i]){//找到汉字的左边界。并加入小根堆。
	  		q.push(i);
	  		break;
		  }
	  }
	  //将数字、字母的左右边界和汉字的右边界加入小根堆
	  int num=0;
	  for(int i=99;i>=2;i--){
	  	if(mp[i]&&!mp[i+1]){//右边界:mp[i]是1,右边是0
	  		q.push(i);
	  		num++;
		  }
		  if(num==13) break; //不算汉字左边界的话,其余边界共13个 
		if(mp[i]&&!mp[i-1]){//左边界:mp[i]是1,左边是0,  
			q.push(i);
			num++;
		}
	  }
	  printf("Case #%d:\n",k); 
	  int ans=0;
	  while(!q.empty()){
	  	ans++;
	  	if(ans%2) cout<<q.top()<<" ";
	  	else cout<<q.top()<<endl;
	  	q.pop();
	  }
	  
	  
	}
	return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值