我使用OpenCVAndroid对图像进行阈值处理是代码和结果
使用OpenCV的方法
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage);
Mat imageMat = new Mat();
Utils.bitmapToMat(bitmap, imageMat);
Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(imageMat, imageMat, 120, 255,Imgproc.THRESH_BINARY);
Utils.matToBitmap(imageMat, bitmap);
得到以下结果
如何改善我的结果,以便在图像中获取穿过小袋的线条位置?
答案 0 :(得分:0)
在尝试各种技术后,我发现在我的情况下不需要阈值处理。能够通过使用以下逻辑找出行:
private void analyzeImage(Uri selectedImage) {
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage);
Mat imageMat = new Mat();
Utils.bitmapToMat(bitmap, imageMat);
Mat rgbMat = imageMat.clone();
Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGR2GRAY);
imageMat = find2BlackLines(imageMat, rgbMat);
Utils.matToBitmap(imageMat, bitmap);
imageView.setImageBitmap(bitmap);
imageMat.release();
rgbMat.release();
saveToInternalStorage(bitmap);
} catch (IOException e) {
}
}
private Mat find2BlackLines(Mat imageMat, Mat rgbMat) {
int lineCount = 0;
ArrayList<Integer> darkLines = new ArrayList<>();
int line_start = imageMat.rows();
int line_end = 0;
double maxLinecount = imageMat.cols() * 0.4;
double midCol = imageMat.cols()/2;
int thresholdCol = (int) midCol/2;
int startingRowCount = getStartingRowCount(imageMat.rows());
boolean line_flag = false;
Timber.d("imageMat.rows() >"+imageMat.rows());
Timber.d("imageMat.cols() >"+imageMat.cols());
Timber.d("maxLinecount >"+maxLinecount);
for (int r = startingRowCount; r >= imageMat.rows()/2; r--) {
lineCount = 0;
for (int c = 0; c <= midCol; c++) {
// if(c >thresholdCol && checkBreakCondition(lineCount, thresholdCol)){
// break;
// }
if(imageMat.get(r,c)==null){
continue;
}
if (imageMat.get(r, c)[0] == 0 || imageMat.get(r,c)[0] <= 120)
lineCount++;
}
Timber.d("lineCount >"+lineCount);
if (lineCount >= maxLinecount) {
line_flag = true;
if (line_start == imageMat.rows()) {
line_start = r;
} else {
line_end = r;
}
} else if (line_flag) {
darkLines.add(line_start);
darkLines.add(line_end);
line_start = imageMat.rows();
line_end = 0;
line_flag = false;
}
if (darkLines.size() == 2)
break;
r=r-20;
}
Timber.d("size of darkKines array >> "+darkLines.size());
if (darkLines.isEmpty() ) {//|| darkLines.size()<3
return imageMat;
}
Timber.d(darkLines.get(0) +" <> "+darkLines.get(1));
// Timber.d(darkLines.get(2) +" <> "+darkLines.get(3));
//BBox for the dark lines
for (int i = 0; i < 1; i++) {
int index_start_row = darkLines.get(i * 2);
int index_end_row = darkLines.get(i * 2 + 1);
Imgproc.rectangle(rgbMat, new Point(0, index_start_row), new Point(imageMat.cols(), index_end_row), new Scalar(255, 0, 0, 255), 10);
}
return rgbMat;
}
基本上iam读取每20行的像素值,如果该值小于120,这是列数的40%,我将其视为黑线。
FYI这个逻辑非常特定于这种情况,如果我们分析不同的图像,这可能不是最好的解决方案。而且我对OpenCV非常陌生