最近遇到如题的问题,语义分割数据集格式是原始图像、标注图像、色号与类别对应的标签。
java实现思路就是读入标注图像,将像素转为类别的二维矩阵,然后对二维矩阵进行同类别的连通域检测,将检测结果保存为ArrayList格式:label,point1(x1,y1),point2(x2,y2)
首先得到文件夹下所有的文件
File file=new File("data/img/");
File[] tempList = file.listFiles();
for (int filei = 0; filei < tempList.length; filei++) {
if (tempList[filei].isFile()) {
}
}
读取文件,获取类别对应标签的hashmap,其中类别与色号用#隔开,由于opencv中无法显示中文,这里用数字代替。之后会有一个数字与类别的hashmap与此类似,不一一列出。
public Map Readtxt(String filename) throws Exception{
//读入标签文件,保存成hashmap的格式
Map labelmap = new HashMap();
File file = new File(filename);
FileReader fr = new FileReader(file);
BufferedReader bf = new BufferedReader(fr);
String line = " ";
int i = 1;
while ((line = bf.readLine()) !=null){
String label[] = line.split(" #");
//labelmap.put(label[1], label[0]);
labelmap.put(label[1], i);
i++;
}
bf.close();
return labelmap;
}
然后将图像像素保存为像素矩阵,有像素值的就用类别代替,没有的置零。
//获取图片的像素矩阵
GetImagePixel gip = new GetImagePixel( );
String colormap [][] = gip.getImagePixel("imgname");
int[][] colorintmap = new int[colormap.length][colormap[0].length];
for(int i=0;i<colormap.length;i++){
for(int j=0;j<colormap[i].length;j++){
if(labelmap.get(colormap[i][j])!=null){
colorintmap[i][j] = (int) ( labelmap.get(colormap[i][j]));}else{
colorintmap[i][j] = 0;
}
}
}
//获取图像中所有像素点的值,返回String的二维数组
public String[][] getImagePixel(String image) throws Exception {
// TODO Auto-generated constructor stub
int[] rgb = new int[3];
File file = new File(image);
System.out.println(file.getName());
BufferedImage bi = null;
try {
bi = ImageIO.read(file);
} catch (Exception e) {
e.printStackTrace();
}
int width = bi.getWidth();
int height = bi.getHeight();
int minx = bi.getMinX();
int miny = bi.getMinY();
//System.out.println("width=" + width + ",height=" + height + ".");
//System.out.println("minx=" + minx + ",miniy=" + miny + ".");
String colormap[][] = new String[width][height];
for (int i = minx; i < width; i++) {
for (int j = miny; j < height; j++) {
int pixel = bi.getRGB(i, j); // 下面三行代码将一个数字转换为RGB数字
rgb[0] = (pixel & 0xff0000) >> 16;
rgb[1] = (pixel & 0xff00) >> 8;
rgb[2] = (pixel & 0xff);
Color pixelcolor = new Color( rgb[0],rgb[1],rgb[2]);
ToHexFromColor thfc = new ToHexFromColor();
String pixelcolorstring = thfc.toHexFromColor(pixelcolor);
colormap[i][j] = pixelcolorstring;
//System.out.println("i=" + i + ",j=" + j + ":(" + pixelcolorstring + ")");
}
}
return colormap;
}
public class ToHexFromColor {
//将RGB转化为String的颜色格式
public String toHexFromColor(Color color){
String r,g,b;
StringBuilder su = new StringBuilder();
r = Integer.toHexString(color.getRed());
g = Integer.toHexString(color.getGreen());
b = Integer.toHexString(color.getBlue());
r = r.length() == 1 ? "0" + r : r;
g = g.length() ==1 ? "0" +g : g;
b = b.length() == 1 ? "0" + b : b;
r = r.toUpperCase();
g = g.toUpperCase();
b = b.toUpperCase();
//su.append("0xFF");
su.append(r);
su.append(g);
su.append(b);
//0xFF0000FF
return su.toString();
}
获取二维数组后,获取二维数组连通域
public ArrayList getCount(int[][] A) {
int result = 0;
ArrayList arraylist = new ArrayList();
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[0].length; j++) {
if (A[i][j] != 0) {
int[] tmp = new int[5];
result++;
tmp = Search.bfs(A, i, j,A[i][j]);
arraylist.add(tmp);
}
}
}
return arraylist;
}
public class Search {
static int dx[] = {0,0,1,-1};
static int dy[] = {1,-1,0,0};
public static void dfs(int[][] A,int i,int j, int tmp){
if(A.length<=0||A[0].length<=0){
return;
}
if(i<0||i>=A.length||j<0||j>=A[0].length||A[i][j]!=tmp){
return;
}
A[i][j]=0;
for(int t=0;t<4;t++){
dfs(A,i+dx[t],j+dy[t],tmp);
}
}
public static int[] bfs(int[][] A,int i,int j, int tmp){
int[] result = {0,0,0,0,0};
if(A.length<=0||A[0].length<=0){
return result;
}
Queue<Integer> queue = new LinkedList<Integer>();
result[0] = tmp;
result[1] = i;
result[2] = j;
result[3] = i;
result[4] = j;
int tp = i*A[0].length+j;
queue.add(tp);
while(!queue.isEmpty()){
tp = queue.poll();
//System.out.println(queue.size());
int nowx = tp/A[0].length;
int nowy = tp%A[0].length;
if(nowx<0||nowx>=A.length||nowy<0||nowy>=A[0].length||A[nowx][nowy]!=tmp){
continue;
}
if(nowx<result[1]){result[1]=nowx;}
if(nowy<result[2]){result[2]=nowy;}
if(nowx>result[3]){result[3]=nowx;}
if(nowy>result[4]){result[4]=nowy;}
A[nowx][nowy] = 0;
for(int t=0;t<4;t++){
int tx = nowx + dx[t];
int ty = nowy + dy[t];
if(tx<0||tx>=A.length||ty<0||ty>=A[0].length||A[tx][ty]!=tmp){
continue;
}
queue.add(tx*A[0].length+ty);
}
}
return result;
}
}
这里用两种方法,第一种是DFS,深度优先遍历,使用堆栈的方式,出现问题栈溢出,所以用第二种方式,BFS,广度优先遍历,使用队列的方式,完美解决问题。
显示图像:
Mat matresult = Highgui.imread("data/img/"+imgname+".jpg");
for(int i = 0;i < result.size(); i ++){
int [] tmp = (int[]) result.get(i);
System.out.println(tmp[0]+" "+tmp[1]+" "+tmp[2]+" "+tmp[3]+" "+tmp[4]);
Core.rectangle(matresult, new Point(tmp[1], tmp[2]), new Point(tmp[3],tmp[4]), new Scalar(0, 0, 255));
Core.putText(matresult, String.valueOf(tmp[0]), new Point(tmp[1], tmp[2]), Core.FONT_HERSHEY_COMPLEX, 1, new Scalar(255, 0, 0));
}
Highgui.imwrite("data/result/"+imgname+".jpg", matresult);
使用opencv时要将opencv的动态链接库引入
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
本文介绍如何将语义分割数据集转换为物体检测格式。通过Java实现,读取标注图像,将像素转换为类别矩阵,利用连通域检测方法(如DFS和BFS)找出物体边界,并保存为ArrayList格式。在处理过程中,使用HashMap映射类别和色号,并解决了opencv显示中文的问题。

2万+

被折叠的 条评论
为什么被折叠?



