日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用OpenCV实现偏斜文档校正

發布時間:2023/12/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用OpenCV实现偏斜文档校正 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

在這篇文章中:

  • 使用OpenCV實現偏斜文檔校正
    • 基于FFT變換以后頻率域梯度
    • 基于離散點求最小外接輪廓
    • 運行結果

使用OpenCV實現偏斜文檔校正

紙質文檔掃描中經常會發生掃描出來的圖像有一定角度的偏斜,對后期的文檔信息化OCR提取造成很大的干擾,導致OCR識別準確率下降從而影響文檔信息化的結果。這個時候可以使用OpenCV對文檔進行糾偏,最常見的文本糾偏算法有兩種,分別是

  • 基于FFT變換以后頻率域梯度
  • 基于離散點求最小外接輪廓

這兩種方法各有千秋,相對來說,第二種方法得到的結果更加準確,第一種基于離散傅立葉變換求振幅的方法有時候各種閾值選擇在實際項目中會有很大問題。

基于FFT變換以后頻率域梯度

主要思路是先把圖像轉換為灰度圖像,然后使用離散傅立葉變換得到圖像在頻率域空間的振幅,對其二值化之后,使用霍夫直線檢測得到角度,然后根據角度完成旋轉校正。代碼實現如下:

Mat src = imread("D:/vcprojects/images/rotate_text.png");Mat gray, binary;cvtColor(src, gray, COLOR_BGR2GRAY);//expand input image to optimal sizeMat padded; int m = getOptimalDFTSize(gray.rows);int n = getOptimalDFTSize(gray.cols); // on the border add zero valuescopyMakeBorder(gray, padded, 0, m - gray.rows, 0, n - gray.cols, BORDER_CONSTANT, Scalar::all(0));Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat complexI;// Add to the expanded another plane with zerosmerge(planes, 2, complexI);// 離散傅立葉變換dft(complexI, complexI); // 實部與虛部得到梯度圖像// planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))split(complexI, planes); magnitude(planes[0], planes[1], planes[0]);Mat magI = planes[0];magI += Scalar::all(1);log(magI, magI);// crop the spectrum, if it has an odd number of rows or columnsmagI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));// rearrange the quadrants of Fourier image so that the origin is at the image centerint cx = magI.cols / 2;int cy = magI.rows / 2;Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrantMat q1(magI, Rect(cx, 0, cx, cy)); // Top-RightMat q2(magI, Rect(0, cy, cx, cy)); // Bottom-LeftMat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-RightMat tmp; // swap quadrants (Top-Left with Bottom-Right)q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp); q2.copyTo(q1);tmp.copyTo(q2);// 歸一化與閾值化顯示normalize(magI, magI, 0, 1.0, NORM_MINMAX);Mat dst;magI.convertTo(dst, CV_8UC1, 255, 0);threshold(dst, binary, 160, 255, THRESH_BINARY);// 霍夫直線vector<Vec2f> lines;Mat linImg = Mat::zeros(binary.size(), CV_8UC3);HoughLines(binary, lines, 1, (float)CV_PI / 180, 30, 0, 0);int numLines = lines.size();float degree = 0.0;for (int l = 0; l<numLines; l++){float rho = lines[l][0], theta = lines[l][1];float offset = CV_PI / 12.0;if (abs(theta) > offset && abs(theta)< (CV_PI / 2.0- offset)) {printf("theta : %.2f\n", theta);degree = (theta)*180-90;}Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));line(linImg, pt1, pt2, Scalar(0, 255, 0), 3, 8, 0);}imshow("lines", linImg);// 旋轉調整Mat rot_mat = getRotationMatrix2D(Point(binary.cols/2, binary.rows/2), degree, 1);Mat rotated;warpAffine(src, rotated, rot_mat, src.size(), cv::INTER_CUBIC, 0, Scalar(255, 255, 255));imshow("input", src);imshow("deskew-demo", rotated);imwrite("D:/deskew_text.png", rotated);

基于離散點求最小外接輪廓

其主要思路是先把圖像二值化,得到一系列離散的前景像素點集合,然后利用輪廓的最小外接矩形函數,得到偏斜的矩形大小與角度,通過仿射變換完成校正。代碼實現如下:

運行結果

  • 原圖

  • 最小外接矩形

  • 校正之后

本文分享自微信公眾號 -?OpenCV學堂(CVSCHOOL)

總結

以上是生活随笔為你收集整理的使用OpenCV实现偏斜文档校正的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。