В случае, если это полезно для всех, большинство решений в этом потоке были обертыванием текста на несколько строк, формы e.
Но потом я нашел это, и он работал:
https://github.com/chunksnbits/jquery-quickfit
Пример использования:
$('.someText').quickfit({max:50,tolerance:.4})
Из вашего входного изображения вам нужно сделать текст белым, а фон - черным
Затем вам нужно вычислить угол поворота ваш счет. Простой подход - найти minAreaRect
всех белых точек (findNonZero
), и вы получите:
Затем вы можете повернуть чтобы текст был горизонтальным:
Теперь вы можете вычислить горизонтальную проекцию (reduce
). Вы можете взять среднее значение в каждой строке. Примените порог th
на гистограмме, чтобы учесть некоторый шум на изображении (здесь я использовал 0
, т. Е. Никакого шума). Линии с только фоном будут иметь значение >0
, текстовые строки будут иметь значение 0
в гистограмме. Затем возьмите среднюю координату бина каждой непрерывной последовательности белых бункеров на гистограмме. Это будет координата y
ваших линий:
Здесь код. Это в C ++, но поскольку большая часть работы связана с функциями OpenCV, она должна быть легко конвертируемой в Python. По крайней мере, вы можете использовать это как ссылку:
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
// Read image
Mat3b img = imread("path_to_image");
// Binarize image. Text is white, background is black
Mat1b bin;
cvtColor(img, bin, COLOR_BGR2GRAY);
bin = bin < 200;
// Find all white pixels
vector<Point> pts;
findNonZero(bin, pts);
// Get rotated rect of white pixels
RotatedRect box = minAreaRect(pts);
if (box.size.width > box.size.height)
{
swap(box.size.width, box.size.height);
box.angle += 90.f;
}
Point2f vertices[4];
box.points(vertices);
for (int i = 0; i < 4; ++i)
{
line(img, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0));
}
// Rotate the image according to the found angle
Mat1b rotated;
Mat M = getRotationMatrix2D(box.center, box.angle, 1.0);
warpAffine(bin, rotated, M, bin.size());
// Compute horizontal projections
Mat1f horProj;
reduce(rotated, horProj, 1, CV_REDUCE_AVG);
// Remove noise in histogram. White bins identify space lines, black bins identify text lines
float th = 0;
Mat1b hist = horProj <= th;
// Get mean coordinate of white white pixels groups
vector<int> ycoords;
int y = 0;
int count = 0;
bool isSpace = false;
for (int i = 0; i < rotated.rows; ++i)
{
if (!isSpace)
{
if (hist(i))
{
isSpace = true;
count = 1;
y = i;
}
}
else
{
if (!hist(i))
{
isSpace = false;
ycoords.push_back(y / count);
}
else
{
y += i;
count++;
}
}
}
// Draw line as final result
Mat3b result;
cvtColor(rotated, result, COLOR_GRAY2BGR);
for (int i = 0; i < ycoords.size(); ++i)
{
line(result, Point(0, ycoords[i]), Point(result.cols, ycoords[i]), Scalar(0, 255, 0));
}
return 0;
}
Основные шаги как @Miki,
- читать источник
- threshed
- find minAreaRect
- warp (g9)
- [gg] [gg] Хотя код в Python:
#!/usr/bin/python3 # 2018.01.16 01:11:49 CST # 2018.01.16 01:55:01 CST import cv2 import numpy as np ## (1) read img = cv2.imread("img02.jpg") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ## (2) threshold th, threshed = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU) ## (3) minAreaRect on the nozeros pts = cv2.findNonZero(threshed) ret = cv2.minAreaRect(pts) (cx,cy), (w,h), ang = ret if w>h: w,h = h,w ang += 90 ## (4) Find rotated matrix, do rotation M = cv2.getRotationMatrix2D((cx,cy), ang, 1.0) rotated = cv2.warpAffine(threshed, M, (img.shape[1], img.shape[0])) ## (5) find and draw the upper and lower boundary of each lines hist = cv2.reduce(rotated,1, cv2.REDUCE_AVG).reshape(-1) th = 2 H,W = img.shape[:2] uppers = [y for y in range(H-1) if hist[y]<=th and hist[y+1]>th] lowers = [y for y in range(H-1) if hist[y]>th and hist[y+1]<=th] rotated = cv2.cvtColor(rotated, cv2.COLOR_GRAY2BGR) for y in uppers: cv2.line(rotated, (0,y), (W, y), (255,0,0), 1) for y in lowers: cv2.line(rotated, (0,y), (W, y), (0,255,0), 1) cv2.imwrite("result.png", rotated)
Наконец, результат:
Canny
для поиска разделительных линий. возможно, вам нравится это видеть. – sturkmen 2 February 2016 в 20:49flip(img, img,1);
послеMat3b img = imread()
– sturkmen 24 May 2016 в 01:38