2016-04-06 11 views
0

Ich versuche, die Kontur jedes Elements in einem Bild mit getrennten musikalischen Notationen zu zeichnen.Opencv Konturrechtecke auf Noten Notation

musical notations

Dies ist der Code, den ich in android/java leite:

public static Bitmap findNotationContours(Bitmap inputImage) { 
Mat inputImageMat = new Mat(); 
Utils.bitmapToMat(inputImage, inputImageMat); 

Imgproc.cvtColor(inputImageMat, inputImageMat, Imgproc.COLOR_BGR2GRAY); 
Imgproc.GaussianBlur(inputImageMat, inputImageMat, new Size(5, 5), 0); 
Imgproc.adaptiveThreshold(inputImageMat, inputImageMat, 255, 1, 1, 11, 2); 

List<MatOfPoint> contours = new ArrayList<>(); 
Mat hierarchy = new Mat(); 
Imgproc.findContours(inputImageMat, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); 

int contourColor = android.R.color.holo_red_dark; 
Scalar contourScalar = new Scalar(Color.red(contourColor), Color.green(contourColor), Color.blue(contourColor)); 

for (int i = 0; i < contours.size(); i++) { 
    Rect rect = Imgproc.boundingRect(contours.get(i)); 
    Imgproc.rectangle(inputImageMat, 
      new Point(rect.x, rect.y), 
      new Point(rect.x + rect.width, rect.y + rect.height), 
      contourScalar, 3); 
} 


Utils.matToBitmap(inputImageMat, inputImage); 
return inputImage; 

}

Das Ergebnis bin ich immer ist:

result

Wenn Sie genug hineinzoomen, können Sie sehen, dass t Die Kontur für die Notationen ist da, aber ich muss das Originalbild mit nur einer Rechteckkontur um jeden von ihnen herum behalten, damit ich diese als Muster speichern kann. Können Sie mir bitte sagen, was ich falsch mache?

+0

Bis Sie in 'inputImageMat' zu zeichnen beginnen, gedreht Sie es bereits in 1-Kanal (Graustufen) Bild, aber Sie ziehen in sie, als ob sie 3 war -Kanal Bild (RGB). –

+0

Ich habe eine andere Matte des ursprünglichen inputImage erstellt und die Rechtecke aus dem 1-Kanal-Bild darauf gezeichnet. Und es hat das Problem behoben. Also vielen Dank. –

Antwort

0

Mit den entscheidenden Informationen aus @Dan Mašek wurde das Problem behoben, ich werde den überarbeiteten Code hinzufügen, der keine Erklärung benötigt, nur dass wir eine Matte mit dem ursprünglichen 3-Kanal-Bild, das wir verwenden, um die Kontur zu zeichnen Rechtecke an.

public static Bitmap findNotationContours(Bitmap inputImage) { 
Mat inputImageMat = new Mat(); 
Mat resultImageMat = new Mat(); 
Utils.bitmapToMat(inputImage, inputImageMat); 
Utils.bitmapToMat(inputImage, resultImageMat); 

Imgproc.cvtColor(inputImageMat, inputImageMat, Imgproc.COLOR_BGR2GRAY); 
Imgproc.GaussianBlur(inputImageMat, inputImageMat, new Size(5, 5), 0); 
Imgproc.adaptiveThreshold(inputImageMat, inputImageMat, 255, 1, 1, 11, 2); 

List<MatOfPoint> contours = new ArrayList<>(); 
Mat hierarchy = new Mat(); 
Imgproc.findContours(inputImageMat, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); 

Scalar contourScalar = new Scalar(255,0,0); 

for (int i = 0; i < contours.size(); i++) { 
    Rect rect = Imgproc.boundingRect(contours.get(i)); 
    Imgproc.rectangle(resultImageMat, 
      new Point(rect.x, rect.y), 
      new Point(rect.x + rect.width, rect.y + rect.height), 
      contourScalar, 3); 
    Log.i("contour", "contour" + i + " x:" + rect.x + " y:" + rect.y); 
} 


Utils.matToBitmap(resultImageMat, inputImage); 
return inputImage; 

}

final result