Обнаружение и исправление перекоса текста
Есть ли способ (используя что-то вроде OpenCV) для обнаружения перекоса текста и исправления его путем поворота изображения? В значительной степени это так?
![enter image description here]()
![enter image description here]()
Поворот изображения кажется достаточно простым, если вы знаете угол, но для изображений, которые я обрабатываю, я не буду... его нужно будет каким-то образом обнаружить.
Ответы
Ответ 1
На основе вашего вышеуказанного комментария здесь приведен код, основанный на учебнике здесь, отлично работающем для вышеуказанного изображения,
Источник
![enter image description here]()
повернутого
![enter image description here]()
Mat src=imread("text.png",0);
Mat thr,dst;
threshold(src,thr,200,255,THRESH_BINARY_INV);
imshow("thr",thr);
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = thr.begin<uchar>();
cv::Mat_<uchar>::iterator end = thr.end<uchar>();
for (; it != end; ++it)
if (*it)
points.push_back(it.pos());
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, box.angle, 1);
//cv::Mat rotated(src.size(),src.type(),Scalar(255,255,255));
Mat rotated;
cv::warpAffine(src, rotated, rot_mat, src.size(), cv::INTER_CUBIC);
imshow("rotated",rotated);
Edit:
Также см. ответ здесь, может быть полезно.
Ответ 2
Я бы предоставил javacv для вашей справки.
package com.test13;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;
public class EdgeDetection {
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
public static void main( String[] args ) throws Exception{
Mat src = Imgcodecs.imread("src//data//inclined_text.jpg");
Mat src_gray = new Mat();
Imgproc.cvtColor(src, src_gray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imwrite("src//data//inclined_text_src_gray.jpg", src_gray);
Mat output = new Mat();
Core.bitwise_not(src_gray, output);
Imgcodecs.imwrite("src//data//inclined_text_output.jpg", output);
Mat points = Mat.zeros(output.size(),output.type());
Core.findNonZero(output, points);
MatOfPoint mpoints = new MatOfPoint(points);
MatOfPoint2f points2f = new MatOfPoint2f(mpoints.toArray());
RotatedRect box = Imgproc.minAreaRect(points2f);
Mat src_squares = src.clone();
Mat rot_mat = Imgproc.getRotationMatrix2D(box.center, box.angle, 1);
Mat rotated = new Mat();
Imgproc.warpAffine(src_squares, rotated, rot_mat, src_squares.size(), Imgproc.INTER_CUBIC);
Imgcodecs.imwrite("src//data//inclined_text_squares_rotated.jpg",rotated);
}
}
Ответ 3
Здесь реализация Python метода профиля проекции для определения перекоса. После получения двоичного изображения идея состоит в том, чтобы поворачивать изображение под различными углами и генерировать гистограмму пикселей в каждой итерации. Чтобы определить angular перекоса, мы сравниваем максимальную разницу между пиками и, используя этот angular перекоса, поворачиваем изображение, чтобы исправить перекос
Входной
![enter image description here]()
Результат
![enter image description here]()
Detected skew angle: -5
import cv2
import numpy as np
from scipy.ndimage import interpolation as inter
def correct_skew(image, delta=1, limit=5):
def determine_score(arr, angle):
data = inter.rotate(arr, angle, reshape=False, order=0)
histogram = np.sum(data, axis=1)
score = np.sum((histogram[1:] - histogram[:-1]) ** 2)
return histogram, score
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
scores = []
angles = np.arange(-limit, limit + delta, delta)
for angle in angles:
histogram, score = determine_score(thresh, angle)
scores.append(score)
best_angle = angles[scores.index(max(scores))]
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
borderMode=cv2.BORDER_REPLICATE)
return best_angle, rotated
if __name__ == '__main__':
image = cv2.imread('1.png')
angle, rotated = correct_skew(image)
print(angle)
cv2.imshow('rotated', rotated)
cv2.imwrite('rotated.png', rotated)
cv2.waitKey()