В приведенном ниже коде я пытаюсь предварительно обработать изображение и с помощью findContours
я пытаюсь извлечь каждый символ как изображение.
Mat inImage = Imgcodecs.imread("CaptureMultiLines.jpg", Imgcodecs.CV_LOAD_IMAGE_COLOR);
Mat destination = new Mat(inImage.rows(), inImage.cols(), inImage.type());
ImageProcUtils.showImage("initial", inImage);
// convert to grayscale
Imgproc.cvtColor(inImage, destination, Imgproc.COLOR_BGR2GRAY);
ImageProcUtils.showImage("grayscaleimage", destination);
Mat binImg = new Mat(inImage.rows(), inImage.cols(), inImage.type());
// binarize the image
double thresh = Imgproc.threshold(destination, binImg, 127, 255, Imgproc.THRESH_BINARY_INV);
ImageProcUtils.showImage("Binary Image", binImg);
// dilation
Mat dilMat = new Mat(inImage.rows(), inImage.cols(), inImage.type());
Mat kernel = Mat.ones(2,1, CvType.CV_8U); // able to extract character
Imgproc.dilate(binImg, dilMat, kernel);
ImageProcUtils.showImage("Dilated Image", dilMat);
// find contours
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(dilMat.clone(), contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
System.out.println();
ImageProcUtils.showImage("Contours", dilMat);
CharacterSegmentation inst = new CharacterSegmentation();
for (int j = 0; j < contours.size(); j++) {
Imgproc.drawContours(dilMat, contours, j, new Scalar(255,0,0));
}
Mat drawing = Mat.zeros( dilMat.size(), CvType.CV_8UC3 );
Point centroid = inst.massCenterMatOfPoint2f(submat);
for( int i = 0; i< contours.size(); i++ )
{
Rect box = Imgproc.boundingRect(contours.get(i));
Mat submat = dilMat.submat(box);
int[] flattenedArr = inst.flattenAnImage(submat);
ImageProcUtils.printArray("Contour.."+i, flattenedArr);
Imgcodecs.imwrite("character-Line"+ i +".jpg", submat);
}
Ниже приведено изображение, которое я использую,
Я могу успешно извлечь символы, но не могу сохранить порядок.Я хочу назвать каждого персонажа в соответствии с его появлением на изображении.Например, F
должен быть назван как Character-0-0
, означая, что это произошло в первой строке и первом столбце.Точно так же, B
как Character-2-7
Я знаю, что существует несколько похожих потоков, например,
Попытка сегментировать символы и сохранить их для файлов изображений.Но контуры рисуются в другом порядке? OpenCV findContours не в порядке Как сортировать контуры слева направо и сверху вниз?
Но, тем не менее, я не знаю, как это реализовать.
Я тоже попробовал приведенный ниже код Python, но все равно не повезло,
import cv2
import numpy as np
image = cv2.imread("D:\\Users\\Downloads\\CaptureMultiLines.jpg")
cv2.imshow('orig',image)
# image = cv2.resize(image_original,None,fx=4, fy=4, interpolation = cv2.INTER_CUBIC)
#grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# original_resized = cv2.resize(gray, (0,0), fx=.2, fy=.2)
cv2.imshow('gray',gray)
cv2.waitKey(0)
#Remove Salt and pepper noise
saltpep = cv2.fastNlMeansDenoising(gray,None,9,13)
# original_resized = cv2.resize(saltpep, (0,0), fx=.2, fy=.2)
cv2.imshow('Grayscale',saltpep)
cv2.waitKey(0)
#blur
blured = cv2.blur(saltpep,(3,3))
# original_resized = cv2.resize(blured, (0,0), fx=.2, fy=.2)
cv2.imshow('blured',blured)
cv2.waitKey(0)
#binary
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
# original_resized = cv2.resize(thresh, (0,0), fx=.2, fy=.2)
cv2.imshow('Threshold',thresh)
cv2.waitKey(0)
#dilation
kernel = np.ones((5,100), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)
# original_resized = cv2.resize(img_dilation, (0,0), fx=.2, fy=.2)
cv2.imshow('dilated',img_dilation)
cv2.waitKey(0)
#find contours
im2,ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[1])
for i, ctr in enumerate(sorted_ctrs):
# Get bounding box
x, y, w, h = cv2.boundingRect(ctr)
# Getting ROI
roi = image[y:y+h, x:x+w]
# # show ROI
cv2.imshow('segment no:' +str(i),roi)
cv2.waitKey(0)
cv2.rectangle(image,(x,y),( x + w, y + h ),(90,0,255),2)
cv2.waitKey(0)
im = cv2.resize(roi,None,fx=4, fy=4, interpolation = cv2.INTER_CUBIC)
ret_1,thresh_1 = cv2.threshold(im,127,255,cv2.THRESH_BINARY_INV)
# original_resized = cv2.resize(thresh, (0,0), fx=.2, fy=.2)
cv2.imshow('Threshold_1',thresh_1)
cv2.waitKey(0)
#dilation
kernel_1 = np.ones((5,5), np.uint8)
img_dilation_1 = cv2.dilate(thresh_1, kernel_1, iterations=1)
# original_resized = cv2.resize(img_dilation, (0,0), fx=.2, fy=.2)
cv2.imshow('dilatedn_loop_1',img_dilation_1)
cv2.waitKey(0)
#find contours
im,ctrs_1, hier = cv2.findContours(img_dilation_1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#sort contours
sorted_ctrs_1 = sorted(ctrs_1, key=lambda ctr: cv2.boundingRect(ctr)[1])
for j, ctr_1 in enumerate(sorted_ctrs_1):
# Get bounding box
x_1, y_1, w_1, h_1 = cv2.boundingRect(ctr_1)
# Getting ROI
roi_1 = image[y_1:y_1+h_1, x_1:x_1+w_1]
# # show ROI
cv2.imshow('Line no: ' + i + "Column no : " + j +str(j),roi_1)
cv2.waitKey(0)
# original_resized = cv2.resize(image, (0,0), fx=.2, fy=.2)
# cv2.imshow('marked areas',original_resized)
cv2.imshow('marked areas',image)
cv2.waitKey(0)