您好,登錄后才能下訂單哦!
小編給大家分享一下opencv怎么利用霍夫變換檢測直線進(jìn)行圖片校正,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
利用霍夫變換檢測直線,校正拍攝傾斜的圖片
#include<opencv2\opencv.hpp> #include <iostream> using namespace cv; using namespace std; #define ERROR 1234 //度數(shù)轉(zhuǎn)換 double DegreeTrans(double theta) { double res = theta / CV_PI * 180; return res; } //逆時針旋轉(zhuǎn)圖像degree角度(原尺寸) void rotateImage(Mat src, Mat& img_rotate, double degree) { //旋轉(zhuǎn)中心為圖像中心 Point2f center; center.x = float(src.cols / 2.0); center.y = float(src.rows / 2.0); int length = 0; length = sqrt(src.cols*src.cols + src.rows*src.rows); //計算二維旋轉(zhuǎn)的仿射變換矩陣 Mat M = getRotationMatrix2D(center, degree, 1); warpAffine(src, img_rotate, M, Size(length, length), 1, 0, Scalar(255, 255, 255));//仿射變換,背景色填充為白色 } //通過霍夫變換計算角度 double CalcDegree(const Mat &srcImage, Mat &dst) { Mat midImage, dstImage; Canny(srcImage, midImage, 50, 200, 3); cvtColor(midImage, dstImage, CV_GRAY2BGR); //通過霍夫變換檢測直線 vector<Vec2f> lines; HoughLines(midImage, lines, 1, CV_PI / 180, 300, 0, 0);//第5個參數(shù)就是閾值,閾值越大,檢測精度越高 //cout << lines.size() << endl; //由于圖像不同,閾值不好設(shè)定,因?yàn)殚撝翟O(shè)定過高導(dǎo)致無法檢測直線,閾值過低直線太多,速度很慢 //所以根據(jù)閾值由大到小設(shè)置了三個閾值,如果經(jīng)過大量試驗(yàn)后,可以固定一個適合的閾值。 if (!lines.size()) { HoughLines(midImage, lines, 1, CV_PI / 180, 200, 0, 0); } //cout << lines.size() << endl; if (!lines.size()) { HoughLines(midImage, lines, 1, CV_PI / 180, 150, 0, 0); } //cout << lines.size() << endl; if (!lines.size()) { cout << "沒有檢測到直線!" << endl; return ERROR; } float sum = 0; //依次畫出每條線段 for (size_t i = 0; i < lines.size(); i++) { float rho = lines[i][0]; float theta = lines[i][1]; Point pt1, pt2; //cout << theta << endl; 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)); //只選角度最小的作為旋轉(zhuǎn)角度 sum += theta; line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, CV_AA); //Scalar函數(shù)用于調(diào)節(jié)線段顏色 imshow("直線探測效果圖", dstImage); } float average = sum / lines.size(); //對所有角度求平均,這樣做旋轉(zhuǎn)效果會更好 cout << "average theta:" << average << endl; double angle = DegreeTrans(average) - 90; rotateImage(dstImage, dst, angle); //imshow("直線探測效果圖2", dstImage); return angle; } void ImageRecify(const char* pInFileName, const char* pOutFileName) { double degree; Mat src = imread(pInFileName); imshow("原始圖", src); int srcWidth, srcHight; srcWidth = src.cols; srcHight = src.rows; cout << srcWidth << " " << srcHight << endl; Mat dst; src.copyTo(dst); //傾斜角度矯正 degree = CalcDegree(src, dst); if (degree == ERROR) { cout << "矯正失??!" << endl; return; } rotateImage(src, dst, degree); cout << "angle:" << degree << endl; imshow("旋轉(zhuǎn)調(diào)整后", dst); Mat resulyImage = dst(Rect(0, 0, srcWidth, srcHight)); //根據(jù)先驗(yàn)知識,估計好文本的長寬,再裁剪下來 imshow("裁剪之后", resulyImage); imwrite("recified.jpg", resulyImage); } int main() { ImageRecify("jiao.jpg", "FinalImage.jpg"); waitKey(); return 0; }
效果圖如下所示:
以上是“opencv怎么利用霍夫變換檢測直線進(jìn)行圖片校正”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。