OpenCV學習筆記(十二)旋轉文字矯正

2021-07-25 08:41:55 字數 4226 閱讀 7974

旋轉文字矯正:

影象文字旋轉通常在仿射變換時獲取影象的傾斜角度,利用傅利葉變換中的時域與頻域的變換關係,實現旋轉文字的校正。

旋轉文字的特徵明顯就是存在分行間隔,當文字影象旋轉時,其頻域中的頻譜也會隨之旋轉。根據這一特徵來計算文字影象的dft變換,dft變換的結果是低頻位於邊界四角,高頻集中在中心區域,將低頻和高頻互換,實現中心的移動,進而可以看到文字影象的頻譜有明顯的傾斜直線,再通過計算傾斜直線的傾斜角度,利用仿射變換就可以完成旋轉文字的影象矯正。

(1)錄入一張影象:

前幾步的處理和傅利葉變化一致,就是生成傅利葉頻譜圖。

(2)頻域中心移動,傅利葉變化得到的低頻部分在邊緣角中,高頻部分在影象中心,對於傾斜文字影象,我們關心的是影象中的低頻部分,因此需要將其與高頻部分互換中心。通常的做法是四等分,繞後進行互調。

(3)傾斜度檢測。

只要檢測出影象直線的傾斜角,就可以進行旋轉文字,方法很多,採用hough變化線檢測方法進行直線傾斜角計算。首先進行二值化,然後根據huogh變換檢測直線的步驟來完成影象中的直線檢測,計算得到影象直線的角度;最後判斷角度是否符合要求,對符合要求的線角度進行影象的角度轉換。

hough變換檢測線:

houghlines

(inputarray image, outputarray lines, double rho, double theta, int threshold,double srn=0,doublestn=0 )

lines:輸出檢測到的線的數量。theta=cv_pi/180;theshold:是閾值,只有大於這個閾值的線,才會被檢測到。

rho:畫素中的距離解析度。

根據檢測的線,繪製出線。

所用函式:

(4)仿射變換矯正

mat getrotationmatrix2d

(point2f center, double angle, double scale)

最終結果:

源程式:

#include #include #include #include using namespace cv;

using namespace std;

mat xuanzhuan(mat srcimage)

; mat mergemat;

//把兩頁合成乙個2通道的mat

merge(groupmats, 2, mergemat);

//對上面合成的mat進行離散傅利葉變換,支援原地操作,傅利葉變換結果為複數,通道1存的是實部,通道2存的是虛部。

dft(mergemat, mergemat);

//把變換的結果分割到各個陣列的兩頁中,方便後續操作

split(mergemat, groupmats);

//求傅利葉變化各頻率的幅值,幅值放在第一頁中

magnitude(groupmats[0], groupmats[1], groupmats[0]);

mat magnitudemat = groupmats[0].clone();

//歸一化操作,幅值加1

magnitudemat += scalar::all(1);

//傅利葉變換的幅度值範圍大到不適合在螢幕上顯示,高值在螢幕上顯示為白點,而低值為黑點,

//高低值的變化無法有效分辨,為了在螢幕上凸顯出高低的變化得連續性,我們可以用對數尺度來替換線性尺度

log(magnitudemat, magnitudemat);

//歸一化

normalize(magnitudemat, magnitudemat, 0,1,cv_minmax);

magnitudemat.convertto(magnitudemat, cv_8uc1, 255, 0);

//imshow("magnitudemat2", magnitudemat);

//重新分配象限,使(0,0)移動到影象中心,

//傅利葉變換之前要對源影象乘以(-1)^(x+y),進行中心化

//這是對傅利葉變換結果進行中心化

int cx = magnitudemat.cols / 2;

int cy = magnitudemat.rows / 2;

mat tmp;

//top-left--為每乙個象限建立roi

mat q0(magnitudemat, rect(0, 0, cx, cy));

//top-right

mat q1(magnitudemat, rect(cx, 0, cx, cy));

//bottom-left

mat q2(magnitudemat, rect(0, cy, cx, cy));

//bottom-right

mat q3(magnitudemat, rect(cx, cy, cx, cy));

//交換象限,(top-left with bottom-right)

q0.copyto(tmp);

q3.copyto(q0);

tmp.copyto(q3);

//交換象限,(top-right with bottom-letf)

q1.copyto(tmp);

q2.copyto(q1);

tmp.copyto(q2);

mat binarymagnmat;

threshold(magnitudemat, binarymagnmat, 155, 255, cv_thresh_binary);

vectorlines;

binarymagnmat.convertto(binarymagnmat, cv_8uc1, 255, 0);

houghlines(binarymagnmat, lines, 1, cv_pi / 180, 100, 0, 0);

cout << "lines.size: " << lines.size() << endl;

mat houghmat(binarymagnmat.size(), cv_8uc3);

//繪製檢測線

for (size_t i = 0; i < lines.size(); i++)

imshow("houghmat", houghmat);

float theta = 0;

//檢測線角度判斷

for (size_t i = 0; i < lines.size(); i++) }

//角度轉換

float angelt = nrows*tan(theta / 180 * cv_pi) / ncols;

theta = atan(angelt) * 180 / cv_pi;

cout << "theta: " << theta << endl;

//取影象中心

point2f centerpoint = point2f(ncols / 2, nrows / 2);

double scale = 1;

//計算旋轉中心

mat warpmat = getrotationmatrix2d(centerpoint, theta, scale);

//仿射變換

mat resultimage(srcgray.size(), srcgray.type());

warpaffine(srcgray, resultimage, warpmat, resultimage.size());

return resultimage;

}int main()

OpenCv3程式設計學習十二

直方圖均衡化 這就是通過拉伸畫素強度分布範圍來增強影象對比度的一種方法。但是均衡化處理後的影象只能是近似均勻分布,均衡化影象的動態範圍擴大了。本質就是擴大量化間隔同時減少了量化級別,所以一些灰度不同的畫素可能會變的相同,最重要的是,均衡化後的如果再對其均衡化,則不會有任何變化 equalizehis...

opencv學習筆記

總的來說,我們學習影象處理的就是從vs和opencv開始的。而在之前的學習中,我們使用了前人的通過或攝像頭的人臉識別 並順利執行了程式。順理成章地,接下來的階段就是將這些 給 吃透 理解並吸收,掌握其中的知識。下面就是今天對於 中幾個重要組成部分的學習心得總結。一 命名空間 using namesp...

openCV學習筆記

1 imread函式 mat imread const string filename,intflags 1 mat image0 imread dota.jpg cv load image anydepth cv load image anycolor 載入最真實的影象 ge1 imread do...