旋轉文字矯正:
影象文字旋轉通常在仿射變換時獲取影象的傾斜角度,利用傅利葉變換中的時域與頻域的變換關係,實現旋轉文字的校正。
旋轉文字的特徵明顯就是存在分行間隔,當文字影象旋轉時,其頻域中的頻譜也會隨之旋轉。根據這一特徵來計算文字影象的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...