我已經成功檢測到包圍盒,現在我想刪除圖像中的所有其他內容,只是保留邊界框的內容以提高tesseract準確性,下面是圖像表示形式所做的和需要(我想要的二進制圖像只包含字母,要刪除所有其他對象):OpenCV Java從場景中刪除對象
和我的代碼:
public static ProcessedFrame preProcessImage(Mat image){
originalFrame = image.clone();
roiColor = image.clone();
Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2GRAY, 0);
originalFrameGrayScale = image.clone();
Mat morph = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9, 9));
Imgproc.morphologyEx(image, image, Imgproc.MORPH_TOPHAT, morph);
Imgproc.Sobel(image, image, -1, 2, 0);
Imgproc.GaussianBlur(image, image, new Size(5,5), 3,3);
Imgproc.morphologyEx(image, image, Imgproc.MORPH_CLOSE, morph);
Imgproc.threshold(image, image, 200, 255, Imgproc.THRESH_OTSU);
Vector<Rect> rectangles = detectionContour(image);
Mat roi = originalFrameGrayScale.clone();
if(!rectangles.isEmpty()){
roi = originalFrameGrayScale.submat(rectangles.get(0));
roiBlack = roi.clone();
roiColor = roiColor.submat(rectangles.get(0));
Imgproc.rectangle(originalFrame, rectangles.get(0).br(), rectangles.get(0).tl(), new Scalar(0,0,255), 2);
}
Imgproc.medianBlur(roi, roi, 3);
Imgproc.adaptiveThreshold(roi, roi, 225, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 15, 3);
Imgproc.medianBlur(roi, roi, 3);
Imgproc.medianBlur(roi, roi, 3);
Imgproc.adaptiveThreshold(roi, roi, 225, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 15, 3);
Imgproc.medianBlur(roi, roi, 3);
roiBinarize = roi.clone();
Mat erode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
Mat dilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(3, 3));
Imgproc.morphologyEx(roi, roi, Imgproc.MORPH_CLOSE, dilate);
Imgproc.morphologyEx(roi, roi, Imgproc.MORPH_CLOSE, erode);
Vector<Rect> letters = detectionPlateCharacterContour(roi);
doTesseractOCR(letters, roiBinarize);
return new ProcessedFrame(originalFrame, roiColor, roiBinarize, roi);
}
private static void doTesseractOCR(Vector<Rect> letters, Mat plate){
Tesseract instance = new Tesseract(); //
instance.setLanguage(LANGUAGE);
String resultPlate = "AAA0000";
for(int i= 0; i < letters.size(); i++){
BufferedImage letter = OpenCvUtils.Mat2bufferedImage(plate.submat(letters.get(i)));
try {
String result = instance.doOCR(letter);
String character = result.replace("\n", "");
resultPlate = new StringBuilder(resultPlate).replace(i ,i+1, character).toString();
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
System.out.println("Tesseract output: "+resultPlate);
}
try {
String result = instance.doOCR(OpenCvUtils.Mat2bufferedImage(roiBinarize));
System.out.println("Tesseract output2: "+result.replace("\n", ""));
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
}
private static Vector<Rect> detectionPlateCharacterContour(Mat roi) {
Mat contHierarchy = new Mat();
Mat imageMat = roi.clone();
Rect rect = null;
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(imageMat, contours, contHierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);
Vector<Rect> rect_array = new Vector<>();
for (int i = 0; i < contours.size(); i++) {
rect = Imgproc.boundingRect(contours.get(i));
double ratio = 0;
if(rect.height > rect.width){
ratio = rect.height/rect.width;
}else{
ratio = rect.width/rect.height;
}
Logger.printMessage("Ratio of letter: "+ratio);
double contourarea = Imgproc.contourArea(contours.get(i));
if (contourarea >= 160 && contourarea <= 1000 && (ratio >= 1 && ratio <= 2)) {
Imgproc.rectangle(roiColor, rect.br(), rect.tl(), new Scalar(10,50,255));
rect_array.add(rect);
}
}
contHierarchy.release();
return rect_array;
}
private static Vector<Rect> detectionContour(Mat outmat) {
Mat contHierarchy = new Mat();
Mat imageMat = outmat.clone();
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(imageMat, contours, contHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);
Vector<Rect> rect_array = new Vector<>();
for (int i = 0; i < contours.size(); i++) {
Rect rect = Imgproc.boundingRect(contours.get(i));
Mat contour = contours.get(i);
double contourarea = Imgproc.contourArea(contour);
double ratio = 0;
int radius = 0;
if(rect.height > rect.width){
ratio = rect.height/rect.width;
radius = rect.height/2;
}else{
ratio = rect.width/rect.height;
radius = rect.width/2;
}
if (contourarea >= 2000 && contourarea <= 10000 && (ratio == 1 || ratio == 2)) {
Logger.printMessage("Rectangle ratio: "+ratio);
MatOfPoint2f mat2f = new MatOfPoint2f();
contours.get(i).convertTo(mat2f, CvType.CV_32FC2);
RotatedRect rotatedRect = Imgproc.minAreaRect(mat2f);
double rotationAngle = rotatedRect.angle;
if(rotatedRect.angle > 0)
rotationAngle = 90 - rotatedRect.angle;
else
rotationAngle = rotatedRect.angle;
Logger.printMessage("Rotation is: "+(rotationAngle));
rect = enlargeROI(originalFrame, rect, 10);
rect_array.add(rect);
}
}
contHierarchy.release();
return rect_array;
}
private Vector<Rect> detectionContours(Mat outmat) {
Mat contHierarchy = new Mat();
Mat imageMat = outmat.clone();
Rect contourRect = null;
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(imageMat, contours, contHierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
Vector<Rect> rect_array = new Vector<>();
for (int i = 0; i < contours.size(); i++) {
Mat contour = contours.get(i);
double contourarea = Imgproc.contourArea(contour);
if (contourarea > minBlob && contourarea < maxBlob) {
contourRect = Imgproc.boundingRect(contours.get(i));
rect_array.add(contourRect);
}
}
contHierarchy.release();
return rect_array;
}
當我運行這段代碼打印出來每一個矩形的形心我發現 2×:18.0 Y:111.0 2×:42.0 Y:109.0 7×:65.0 Y:108.0 0X:89.0 Y:108.0 甲X:29.0 Y:61.0 ÇX: 52.0 y:58.0 x:77.0 y:58.0
的[OpenCV的增強圖像OCR]可能的複製(http://stackoverflow.com/questions/43958962/opencv-enhancing-image-for-ocr) - 請不要發佈關於顯然是同一問題的另一個問題,而是適當地增強原始問題。 –
我刪除了帖子,它被錯誤地詢問。 –
OK :) |你想替換「刪除」圖像的哪些部分? (我假設我們正在討論關於附加圖像右下角的圖像的一些進一步的步驟。)由於您提供了一個邊界框向量,用於指定個別檢測到的字母,我認爲這只是一些外觀要求用於顯示? –