Boooil's BLOG.

图像特征匹配开发手记Vol_8

2021/02/03 Share

(区域获取+文件名获取+匹配)组合模块


整体思路:

首先获得区域号,通过区域号获取区域文件夹下所有对比图片的路径名File_list。由于我们需要的是用户输入的图片与每一类别的对比图片的得分,所以需要将File_list进行二次分割,将同类建筑分到一组,进而进行对比。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
AreaSearch areaSearch = new AreaSearch();
FileName fileName = new FileName();

List<District> district_list = areaSearch.Creat_District();
LatLng location = new LatLng(40.005835,116.359258);
int district_num = areaSearch.getDistrict(location,district_list);
System.out.println("当前坐标区号"+district_num);

String FilePath = "pic_set/"+Integer.toString(district_num);
System.out.println("当前目录名:"+FilePath);

List<String> File_list = new ArrayList<String>(fileName.getFilesAllName(FilePath,this));
//for(int i=0;i<File_list.size();i++)
//System.out.println("获取的文件名:"+ File_list.get(i));
progressBar.setMax(File_list.size());
File_list.add(0, String.valueOf(district_num));
File_list.add(0,"/assets/pic_set/2/BoyDorm_1.jpg");//用户传入图片
task.execute(File_list);

这一部分是对File_list进行一些预处理。因为AsyncTask传入参数只能有一个,但是我们需要用户图片路径区域号以及对比图片集这三个参数,为了简单起见,我们就把前两个参数add进对比图片集File_list中,使用前提取出来再删去即可。

这里动态设置了progressbar的总长度,依据对比图片集的数量变化而变化。


AsyncTask的doInBackground函数是核心部分,这里最后的得分计算并没有完善。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@Override
protected Double doInBackground(List<String>... lists) {
List<String> File_list = new ArrayList<String>(lists[0]);
//第二版---------------------------------------------------//
//File_list包括当前区域所有的数据图片以及用户传入的图片
//首先把用户传入图片和区域号拿出来
String TrainFile_Path = "";
String TestFile_Path = File_list.remove(0);
String district_num = File_list.remove(0);
int progress =0;//进度条进度
double sum =0;
while(File_list.isEmpty()==false) {
String construction_name = File_list.get(0).split("_")[0];
System.out.println("construction_name:"+construction_name);
int count = 0;
for (int i = 1; i < File_list.size(); i++) {
String file = File_list.get(i);
String S = file.split("_")[0];
if (construction_name.equals(S)) {
count++;
}
else break;
}
List<String> newFile_list = new ArrayList<String>(File_list.subList(0, count+1));
for(int i=0;i<newFile_list.size();i++){
newFile_list.set(i,"/assets/pic_set/"+district_num+"/"+newFile_list.get(i));
System.out.println("获取的文件名:"+ newFile_list.get(i));
}

//进行匹配,newFile_list就是匹配图片组
Bitmap src_bitmap1= BitmapFactory.decodeStream(getClass().getResourceAsStream(TestFile_Path));
src_bitmap1 = Bitmap.createScaledBitmap(src_bitmap1,960,540,true);
sum =0;
for(int i=0;i<newFile_list.size();i++){
//TrainFile_Path = "/assets/pic_set/2/BoyDorm_" + i +".jpg";
TrainFile_Path = newFile_list.get(i);
//System.out.println(TrainFile_Path);
Bitmap src_bitmap2 = BitmapFactory.decodeStream(getClass().getResourceAsStream(TrainFile_Path));
src_bitmap2 = Bitmap.createScaledBitmap(src_bitmap2,960,540,true);
FeatureMatch featureMatch = new FeatureMatch();
sum += featureMatch.Score(src_bitmap1,src_bitmap2);
System.out.println("得分:"+featureMatch.Score(src_bitmap1,src_bitmap2));
progress += 1;
publishProgress(progress);
}
//sum = sum/newFile_list.size()-1;

if(count>File_list.size()-1){
File_list = null;
}
else
File_list = File_list.subList(count + 1, File_list.size());
}
return sum;
//-------------------------------------------------------------//
}

一开始便是把用户传入图片和区域号拿出来,使用List的remove函数很容易实现。

1
2
3
4
//首先把用户传入图片和区域号拿出来
String TrainFile_Path = "";
String TestFile_Path = File_list.remove(0);
String district_num = File_list.remove(0);

之后是对比图片集的分类,因为命名的规范(参考之前的博客),所以将“_”作为分隔符,将每条图片路径中的建筑物名称提取出来,遍历,如果相同,则序号count向后推;如果出现了不同,说明从0到count都是同一类别,使用sublist进行切分即可。得到的newFile_list就是分类后的对比图片集。

0到count是我们目前放入对比的图片集,切分剩下的File_list放到下一轮,如此反复切分,直到不能切分为止。判断能否切分的条件是count是否大于整个File_list长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
while(File_list.isEmpty()==false) {
String construction_name = File_list.get(0).split("_")[0];
System.out.println("construction_name:"+construction_name);
int count = 0;
for (int i = 1; i < File_list.size(); i++) {
String file = File_list.get(i);
String S = file.split("_")[0];
if (construction_name.equals(S)) {
count++;
}
else break;
}
List<String> newFile_list = new ArrayList<String>(File_list.subList(0, count+1));
for(int i=0;i<newFile_list.size();i++){
newFile_list.set(i,"/assets/pic_set/"+district_num+"/"+newFile_list.get(i));
System.out.println("获取的文件名:"+ newFile_list.get(i));
}

//进行匹配,newFile_list就是匹配图片组
//代码先略

if(count>File_list.size()-1){
File_list = null;
}
else
File_list = File_list.subList(count + 1, File_list.size());
}

匹配部分将newFile_list中的图片一一与用户传入图片进行匹配,调用之前写的匹配方法即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//进行匹配,newFile_list就是匹配图片组
Bitmap src_bitmap1= BitmapFactory.decodeStream(getClass().getResourceAsStream(TestFile_Path));
src_bitmap1 = Bitmap.createScaledBitmap(src_bitmap1,960,540,true);
sum =0;
for(int i=0;i<newFile_list.size();i++){
//TrainFile_Path = "/assets/pic_set/2/BoyDorm_" + i +".jpg";
TrainFile_Path = newFile_list.get(i);
//System.out.println(TrainFile_Path);
Bitmap src_bitmap2 = BitmapFactory.decodeStream(getClass().getResourceAsStream(TrainFile_Path));
src_bitmap2 = Bitmap.createScaledBitmap(src_bitmap2,960,540,true);
FeatureMatch featureMatch = new FeatureMatch();
sum += featureMatch.Score(src_bitmap1,src_bitmap2);
System.out.println("得分:"+featureMatch.Score(src_bitmap1,src_bitmap2));
progress += 1;
publishProgress(progress);
}

至此,从assests文件夹获取对比图片集并进行遍历匹配的组合模块已经基本搭建起来,目前需要解决的问题是获取用户图片以及老生常谈的识别精度问题,因为发现准确率还是没有想象中的好。