我正在创建一个与图像中的牌照提取相关的Android应用程序。我提取牌照的算法基于图像中对象(blob)的连接组件标签。在matlab中,我可以使用bwlabel()轻松执行CCL,但我无法在android(eclipse IDE)中找到类似bwlabel的内容
是否有一些预定义的方法或任何其他方式可以帮助我在Android中标记图像中的对象?
答案 0 :(得分:2)
伙计,我在Java方面表现不佳,但我创建了自己的连接组件标签类。使用TwoPass功能:
public class ConnectedComponentsLabelling {
public static int[][] twoPass(int[][] matrix) {
int nextLabel = 1;
int rowLength = matrix.length;
int columnLength = matrix[0].length;
List<Set<Integer>> linked = new ArrayList<Set<Integer>>();
int[][] labels = new int[rowLength][columnLength];
//Primeiro Passo
for (int row = 0; row < rowLength; row++) {
for (int column = 0; column < columnLength; column++) {
if (matrix[row][column] != 0) {
int[] neibours = neibours(row, column, labels);
if (neibours.length == 0) {
linked.add(new HashSet());
linked.get(nextLabel - 1).add(nextLabel);
labels[row][column] = nextLabel;
nextLabel += 1;
} else {
Arrays.sort(neibours);
labels[row][column] = neibours[0];
for (int i = 0; i < neibours.length; i++) {
for (int j = 0; j < neibours.length; j++) {
linked.get(neibours[i] - 1).add(neibours[j]);
}
}
}
}
}
}
//Segundo Passo
int[] vector = new int[nextLabel];
for (int i= 0; i < nextLabel - 1; i++){
vector[i] = Collections.min(linked.get(i), null);
}
for (int row = 0; row < rowLength; row++) {
for (int column = 0; column < columnLength; column++) {
if (matrix[row][column] != 0) {
labels[row][column] = vector[labels[row][column] - 1];
}
}
}
return labels;
}
public static int[] neibours(int row, int column, int[][] matrix) {
int[] neibours = {};
int rowLength = matrix.length;
int columnLength = matrix[0].length;
if (row ==0 && column ==0) { return neibours;
}
else if (row == 0) {
neibours = add_element(matrix[row][column - 1], neibours);
} else if (column == 0) {
neibours = add_element(matrix[row - 1][column], neibours);
} else if ((row > 0) && (column > 0) && (column < columnLength - 1)) {
neibours = add_element(matrix[row][column - 1], neibours);
neibours = add_element(matrix[row - 1][column - 1], neibours);
neibours = add_element(matrix[row - 1][column], neibours);
neibours = add_element(matrix[row - 1][column + 1], neibours);
} else if (row > 0 && column > 0) {
neibours = add_element(matrix[row][column - 1], neibours);
neibours = add_element(matrix[row - 1][column - 1], neibours);
neibours = add_element(matrix[row - 1][column], neibours);
}
int[] neibours2 = {};
for (int i = 0; i < neibours.length; i++) {
if (neibours[i] != 0) {
neibours2 = add_element(neibours[i], neibours2);
}
}
return neibours2;
}
public static int max(int[] vector){
int max = 0;
for (int number = 0; number < vector.length; number++) {
if (number > max){max = number;}
}
return max;
}
public static int[] areaCount(int[][] matrix){
int[] vectorLabel = {};
int[] vectorArea = {};
int positionNew = 0;
boolean teste;
int rowLength = matrix.length;
int columnLength = matrix[0].length;
for (int row = 0; row < rowLength; row++) {
for (int column = 0; column < columnLength; column++) {
teste = true;
for (int position = 0; position < vectorLabel.length; position++){
if (vectorLabel[position] == matrix[row][column]) {positionNew = position; teste = false;}
}
if (teste){
vectorLabel = add_element(matrix[row][column], vectorLabel);
vectorArea = add_element(1, vectorArea);
} else {
vectorArea[positionNew] = vectorArea[positionNew] + 1;
}
}
}
return vectorArea;
}
public static int[] add_element(int element, int[] neibours) {
neibours = Arrays.copyOf(neibours, neibours.length + 1);
neibours[neibours.length - 1] = element;
return neibours;
}
}
但是我不建议使用它,因为它太慢了......更好地导入OPENCV并使用类似这个想法的findCountours,但它是用C语言编写的。
我在一个代码中使用它来查找图像中不同元素的区域:
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat imgMat = new Mat();
List<Double> areasList = new ArrayList<Double>();
Imgproc.findContours(imgMat, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE);
//matrix = ConnectedComponentsLabelling.twoPass(matrix);
for (int idx = 0; idx < contours.size(); idx++) {
Mat contour = contours.get(idx);
double contourarea = Imgproc.contourArea(contour);
areasList.add(contourarea);
}