语义分割数据集转物体检测

本文介绍如何将语义分割数据集转换为物体检测格式。通过Java实现,读取标注图像,将像素转换为类别矩阵,利用连通域检测方法(如DFS和BFS)找出物体边界,并保存为ArrayList格式。在处理过程中,使用HashMap映射类别和色号,并解决了opencv显示中文的问题。

最近遇到如题的问题,语义分割数据集格式是原始图像、标注图像、色号与类别对应的标签。
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);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值