opencv利用霍夫變換檢測(cè)直線進(jìn)行圖片校正
利用霍夫變換檢測(cè)直線,校正拍攝傾斜的圖片
#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; } //逆時(shí)針旋轉(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); //計(jì)算二維旋轉(zhuǎn)的仿射變換矩陣 Mat M = getRotationMatrix2D(center, degree, 1); warpAffine(src, img_rotate, M, Size(length, length), 1, 0, Scalar(255, 255, 255));//仿射變換,背景色填充為白色 } //通過(guò)霍夫變換計(jì)算角度 double CalcDegree(const Mat &srcImage, Mat &dst) { Mat midImage, dstImage; Canny(srcImage, midImage, 50, 200, 3); cvtColor(midImage, dstImage, CV_GRAY2BGR); //通過(guò)霍夫變換檢測(cè)直線 vector<Vec2f> lines; HoughLines(midImage, lines, 1, CV_PI / 180, 300, 0, 0);//第5個(gè)參數(shù)就是閾值,閾值越大,檢測(cè)精度越高 //cout << lines.size() << endl; //由于圖像不同,閾值不好設(shè)定,因?yàn)殚撝翟O(shè)定過(guò)高導(dǎo)致無(wú)法檢測(cè)直線,閾值過(guò)低直線太多,速度很慢 //所以根據(jù)閾值由大到小設(shè)置了三個(gè)閾值,如果經(jīng)過(guò)大量試驗(yàn)后,可以固定一個(gè)適合的閾值。 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 << "沒(méi)有檢測(cè)到直線!" << endl; return ERROR; } float sum = 0; //依次畫(huà)出每條線段 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("直線探測(cè)效果圖", dstImage); } float average = sum / lines.size(); //對(duì)所有角度求平均,這樣做旋轉(zhuǎn)效果會(huì)更好 cout << "average theta:" << average << endl; double angle = DegreeTrans(average) - 90; rotateImage(dstImage, dst, angle); //imshow("直線探測(cè)效果圖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)知識(shí),估計(jì)好文本的長(zhǎng)寬,再裁剪下來(lái) imshow("裁剪之后", resulyImage); imwrite("recified.jpg", resulyImage); } int main() { ImageRecify("jiao.jpg", "FinalImage.jpg"); waitKey(); return 0; }
效果圖如下所示:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)簡(jiǎn)易選課系統(tǒng)代碼分享
這篇文章主要介紹了C++實(shí)現(xiàn)簡(jiǎn)易選課系統(tǒng)及實(shí)現(xiàn)代碼的分享,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-01-01C++類和對(duì)象實(shí)戰(zhàn)之Date類的實(shí)現(xiàn)方法
C++ 標(biāo)準(zhǔn)庫(kù)沒(méi)有提供所謂的日期類型,C++ 繼承了C語(yǔ)言用于日期和時(shí)間操作的結(jié)構(gòu)和函數(shù),這篇文章主要給大家介紹了C++類和對(duì)象實(shí)戰(zhàn)之Date類的實(shí)現(xiàn)方法,需要的朋友可以參考下2021-12-12c++ STL set_difference set_intersection set_union 操作
這篇文章主要介紹了c++ STL set_difference set_intersection set_union 操作,需要的朋友可以參考下2017-03-03養(yǎng)成良好的C++編程習(xí)慣之內(nèi)存管理的應(yīng)用詳解
"養(yǎng)成良好的編程習(xí)慣"其實(shí)是相當(dāng)綜合的一個(gè)命題,可以從多個(gè)角度、維度和層次進(jìn)行論述和評(píng)判,如代碼的風(fēng)格、效率和可讀性;模塊設(shè)計(jì)的靈活性、可擴(kuò)展性和耦合度等等,要試圖把所有方面都闡述清楚必須花很多的精力,而且也不一定能闡述得全面2013-05-05零基礎(chǔ)學(xué)習(xí)C/C++需要注意的地方
這篇文章主要介紹了零基礎(chǔ)學(xué)習(xí)C/C++需要注意的地方,文中講解非常細(xì)致,供大家參考和學(xué)習(xí),想要學(xué)習(xí)C/C++的可以閱讀此文2020-06-06C++在成員函數(shù)中使用STL的find_if函數(shù)實(shí)例
這篇文章主要介紹了C++在成員函數(shù)中使用STL的find_if函數(shù)實(shí)例,包括了STL中find_if函數(shù)的具體用法及相關(guān)的完整實(shí)例,非常具有參考借鑒價(jià)值,需要的朋友可以參考下2014-10-10C語(yǔ)言深入分析整形數(shù)據(jù)存儲(chǔ)
C語(yǔ)言中,我們經(jīng)常使用數(shù)據(jù)類型,那么整形數(shù)據(jù)在內(nèi)存中如何存儲(chǔ)?存儲(chǔ)方式是什么?如果你對(duì)這些內(nèi)容不太了解的話,相信看完這篇博客后,你會(huì)對(duì)整形數(shù)據(jù)的存儲(chǔ)有一個(gè)新的認(rèn)識(shí)。話不多說(shuō),我們進(jìn)入正題2022-08-08C++中的按位與&、按位與或|、按位異或^運(yùn)算符詳解
這篇文章主要介紹了C++中的按位與&、按位與或|、按位異或^運(yùn)算符,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01