Я пытался взять еженедельное pdf меню и разделить его на поля сетки для обрезки, а затем OCR, каждый с TesseractOCR.
я видел lineJunctions который может быть полезен здесь, но не смог найти их в документации imagemagick php. Я также видел Hough Lines в похожем вопросе, но опять же не смог найти их в документации php.
//read the image
$im = new Imagick();
$im->readimage('menu.png');
//resize and contrast
$im->resizeImage($im->getImageWidth()/6, $im->getImageHeight()/6 , 9, 1);
$im->thresholdImage( 0.65 * Imagick::getQuantum() );;
//remove "noise"//this is done by creating two new images where only horizontal lines, then vertical are preserved using morphology and then combined into one
$horizontalLines = clone $im;
$verticalLines = clone $im;
$horizontalLineKernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_RECTANGLE, "19x1");
$horizontalLines->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $horizontalLineKernel);
$verticalLineKernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_RECTANGLE, "1x15");
$verticalLines->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $verticalLineKernel);
$horizontalLines->compositeimage($verticalLines, 5, 0, 0);
$im = clone $horizontal;
$horizontalLines->clear();
$horizontalLines->destroy();
$verticalLines->clear();
$verticalLines->destroy();
// Create boxes at corners
// These are at points from which I intent to create the individual grid boxes
$plusKernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_PLUS, "4");
$im->morphology(\Imagick::MORPHOLOGY_OPEN, 1, $plusKernel);
$squareKernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_SQUARE, "2");
$im->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $squareKernel);
Делая это, я получаю изображение с полями, которые, если я могу получить x, y, ширину и высоту, я смогу получить координаты, однако он пропускает правый нижний угол и очень грязный. Я уверен, что должен быть лучший подход.
Изображение уменьшено, а затем я планирую увеличить координаты на 6, как видно на $im->resizeImage()
, Есть ли лучший способ, которым я должен идти об этом?
Один из способов сделать это (предполагая, что линии являются горизонтальными и вертикальными) в ImageMagick — это масштабировать до одной строки и до одного столбца, порога и фильтра txt: output для черных пикселей.
xlist=`convert cells.png -scale x1! -auto-level -threshold 27% -negate -morphology Thinning:-1 Skeleton -negate txt:- | grep "black" | cut -d, -f1`
echo "$xlist"38
109
180
251
322
394
465
536ylist=`convert cells.png -scale 1x! -auto-level -threshold 27% -negate -morphology Thinning:-1 Skeleton -negate txt:- | grep "black" | cut -d: -f1 | cut -d, -f2`
echo "$ylist"45
141
256
381
Комбинация всех значений x и всех значений y дает вам массив пересечений.
xArr=($xlist)
yArr=($ylist)
numx=${#xArr[*]}
numy=${#yArr[*]}
pointlist=""for ((j=0; j<numy; j++)); do
for ((i=0; i<numx; i++)); do
pointlist="$pointlist ${xArr[$i]},${yArr[$j]}"done
done
echo "pointlist=$pointlist"pointlist= 38,45 109,45 180,45 251,45 322,45 394,45 465,45 536,45 38,141 109,141 180,141 251,141 322,141 394,141 465,141 536,141 38,256 109,256 180,256 251,256 322,256 394,256 465,256 536,256 38,381 109,381 180,381 251,381 322,381 394,381 465,381 536,381
Вы можете визуализировать с помощью:
convert cells.png -scale x1! -scale 550x50! -auto-level -threshold 27% tmp1.png
convert cells.png -scale 1x! -scale 50x425! -auto-level -threshold 27% tmp2.png
Без утончения верхняя горизонтальная линия толще одного пикселя.
Других решений пока нет …