国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

這篇具有很好參考價(jià)值的文章主要介紹了OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言:

相信很多人手機(jī)里都裝了個(gè)“掃描全能王”APP,平時(shí)可以用它來(lái)可以掃描一些證件、文本,確實(shí)很好用,第一次用的時(shí)候確實(shí)感覺(jué)功能很強(qiáng)大啊算法很牛逼啊。但是仔細(xì)一想,其實(shí)這些實(shí)現(xiàn)起來(lái)也是很簡(jiǎn)單的,我想了下,實(shí)現(xiàn)的步驟應(yīng)該就只有下面三個(gè):

  1. 將證件輪廓找到

  1. 提取證件矩形輪廓四點(diǎn)進(jìn)行透視變換

  1. 二值化

知道原理之后,我馬上利用強(qiáng)大的opencv開(kāi)發(fā)一個(gè)類(lèi)似“全能掃描王”掃描工具。

整理一下我們要制作的這個(gè)掃描工具有哪些功能:

  1. 圖像的信息區(qū)域的提取與矯正

  1. 圖像的二值化

  1. 銳化和增強(qiáng)

第二第三點(diǎn)都非常簡(jiǎn)單,那么制作這個(gè)工具的難點(diǎn)完全落在了第一點(diǎn)“ 圖像的信息區(qū)域的提取與矯正”上了。在編碼實(shí)現(xiàn)的過(guò)程中,確實(shí)有很多坑需要踩一踩。

效果圖:

我們先展示一下效果,我們有這么一個(gè)用手機(jī)拍攝的圖片

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

經(jīng)過(guò)掃描工具一番處理后變成這樣子。也就是說(shuō),我們將原圖中的那個(gè)文件摳了了出來(lái),并且完成矯正。

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

實(shí)現(xiàn)過(guò)程查閱了大量資料,也看了網(wǎng)上很多類(lèi)似的博客,前輩們實(shí)現(xiàn)過(guò)相類(lèi)似的透視變換的代碼,但是他們的代碼實(shí)現(xiàn)的都不理想,很多圖片根本沒(méi)法檢測(cè)。不過(guò)還是可以從前人的經(jīng)驗(yàn)中獲取到很多好想法的。

代碼實(shí)現(xiàn):

第一步,二值化+高斯濾波+膨脹+canny邊緣提取

一開(kāi)始我是沒(méi)有采取形態(tài)學(xué)處理的,僅僅是二值化+高斯濾波+canny邊緣提取的策略,但是實(shí)際運(yùn)行下效果并不好,原因在于有一些圖片的信息區(qū)域輪廓沒(méi)法閉合,這就導(dǎo)致了信息區(qū)域輪廓沒(méi)法提取。但是加入適當(dāng)?shù)呐蛎浐?,效果就好多了?/p>

Matsrc= imread("1.png");
    imshow("src img", src);
    Matsource= src.clone();

    Matbkup= src.clone();

    Matimg= src.clone();
    cvtColor(img, img, CV_RGB2GRAY);   //二值化
    imshow("gray", img);
    //equalizeHist(img, img);//imshow("equal", img);
    GaussianBlur(img, img, Size(5, 5), 0, 0);  //高斯濾波//獲取自定義核Matelement= getStructuringElement(MORPH_RECT, Size(3, 3)); //第一個(gè)參數(shù)MORPH_RECT表示矩形的卷積核,當(dāng)然還可以選擇橢圓形的、交叉型的//膨脹操作
    dilate(img, img, element);  //實(shí)現(xiàn)過(guò)程中發(fā)現(xiàn),適當(dāng)?shù)呐蛎浐苤匾?    imshow("dilate", img);
    Canny(img, img, 30, 120, 3);   //邊緣提取
    imshow("get contour", img);
}

輪廓提取效果如下:

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

第二步,輪廓查找并篩選

一般情況下,我們提取到的輪廓不會(huì)像上圖那樣的干凈,而是帶有很多干擾項(xiàng)輪廓,如果我們不能很好的剔除這些輪廓,我們根本沒(méi)法找出我們想要的信息區(qū)域。我篩選輪廓的方法很簡(jiǎn)單,就是找出一張圖片中面積最大的那個(gè)輪廓作為我們的信息區(qū)域輪廓,這招真是屢試不爽,因?yàn)楦鶕?jù)我們?nèi)粘=?jīng)驗(yàn),我們對(duì)一張證件或者文件性掃描拍攝,證件區(qū)域占整張圖片的面積肯定是最大的。

    vector<vector<Point> > contours;
    vector<vector<Point> > f_contours;
    std::vector<cv::Point> approx2;
    //注意第5個(gè)參數(shù)為CV_RETR_EXTERNAL,只檢索外框  findContours(img, f_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //找輪廓//求出面積最大的輪廓int max_area = 0;
    int index;
    for (int i = 0; i < f_contours.size(); i++)
    {
        double tmparea = fabs(contourArea(f_contours[i]));
        if (tmparea > max_area)
        {
            index = i;
            max_area = tmparea;
        }

    }
    contours.push_back(f_contours[index]);

篩選出我們所需的輪廓

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

第三步,找出這個(gè)四邊形輪廓的四個(gè)頂點(diǎn)

因?yàn)槲覀冃枰喞乃膫€(gè)頂點(diǎn)坐標(biāo)來(lái)實(shí)現(xiàn)透視變換,現(xiàn)在的問(wèn)題來(lái)了:我們?cè)趺蠢眠@個(gè)四邊形輪廓的點(diǎn)集來(lái)找出初四邊形的四個(gè)頂點(diǎn)?

這真是一個(gè)大難題!

一開(kāi)始我的想法是這樣子的:直接從四邊形點(diǎn)集中篩選出四個(gè)定點(diǎn)(比如x坐標(biāo)最大的那個(gè)坐標(biāo)肯定是四邊形右上角坐標(biāo)或者右下角坐標(biāo),x坐標(biāo)最小的那個(gè)坐標(biāo)肯定是左上角或者下角的那個(gè)坐標(biāo),如此類(lèi)推),但是這種想法實(shí)現(xiàn)起來(lái)是很有問(wèn)題的而因?yàn)樗苁芟抻谒倪呅蔚淖藨B(tài),所以一個(gè)思路一直沒(méi)法進(jìn)行下去。如果大家有僅依賴(lài)四邊形點(diǎn)集就能找出四邊形的四個(gè)頂點(diǎn)坐標(biāo)的方法,請(qǐng)告訴我,我們一同探討。

所以我切換了另外一個(gè)思路:基于直線交點(diǎn)的思路。我們首先使用霍夫變換找出四邊形的邊,然后求兩兩直線的交點(diǎn)不就是四邊形的定點(diǎn)嗎?的確是這樣子的,但是實(shí)際操作起來(lái)也是問(wèn)題多多啊。

最大的問(wèn)題就是,我們?cè)趺幢WC我們使用霍夫變換找到的直線剛好就是形成四邊形的四條直線?

所以我們就必須不斷地去改變霍夫變換的參數(shù),不斷迭代,來(lái)求出一個(gè)可以形成四邊形的直線情況。

那什么情況的直線我們不能接受?

  1. 兩兩直線過(guò)于接近我們排除

  1. 兩兩直線沒(méi)有交點(diǎn)我們排除

  1. 檢測(cè)出來(lái)的直線數(shù)目不是4條我們排除

如果找到了滿(mǎn)足條件的四條直線,我們就可以去計(jì)算他們的交點(diǎn)了。算法如下:

cv::Point2fcomputeIntersect(cv::Vec4i a, cv::Vec4i b)
{
    int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3];
    int x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];

    if (float d = ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)))
    {
        cv::Point2f pt;
        pt.x = ((x1*y2 - y1*x2) * (x3 - x4) - (x1 - x2) * (x3*y4 - y3*x4)) / d;
        pt.y = ((x1*y2 - y1*x2) * (y3 - y4) - (y1 - y2) * (x3*y4 - y3*x4)) / d;
        return pt;
    }
    elsereturn cv::Point2f(-1, -1);
}

計(jì)算出四個(gè)交點(diǎn)后,我們不能完全信任他們就是我們要找的四個(gè)頂點(diǎn),所以繼續(xù)篩選:

  1. 如果兩兩定點(diǎn)的距離過(guò)近,我們排除

bool IsGoodPoints = true;

//保證點(diǎn)與點(diǎn)的距離足夠大以排除錯(cuò)誤點(diǎn)for (int i = 0; i < corners.size(); i++)
{
for (int j = i + 1; j < corners.size(); j++)
{
    int distance = sqrt((corners[i].x - corners[j].x)*(corners[i].x - corners[j].x) + (corners[i].y - corners[j].y)*(corners[i].y - corners[j].y));
    if (distance < 5)
    {
        IsGoodPoints = false;
    }
}
}

if (!IsGoodPoints) continue;
  1. 如果這四個(gè)點(diǎn)構(gòu)成不了四邊形我們排除

  cv::approxPolyDP(cv::Mat(corners), approx, cv::arcLength(cv::Mat(corners), true) * 0.02, true);

if (lines.size() == 4 && corners.size() == 4 && approx.size() == 4)
{
    flag = 1;
    break;
}

如果都通過(guò)以上篩選條件的,我們就可以認(rèn)為他們就是我們找的那四個(gè)頂點(diǎn),這時(shí)我們就可以停止迭代,進(jìn)行頂點(diǎn)排序,即確定這四個(gè)頂點(diǎn)哪個(gè)是左上角點(diǎn),哪個(gè)又是右下點(diǎn)。

算法如下:

boolx_sort(const Point2f & m1, const Point2f & m2){
    return m1.x < m2.x;
}

//確定四個(gè)點(diǎn)的中心線voidsortCorners(std::vector<cv::Point2f>& corners,
    cv::Point2f center){
    std::vector<cv::Point2f> top, bot;
    vector<Point2f> backup = corners;

    sort(corners, x_sort);  //注意先按x的大小給4個(gè)點(diǎn)排序for (int i = 0; i < corners.size(); i++)
    {
        if (corners[i].y < center.y && top.size() < 2)    //這里的小于2是為了避免三個(gè)頂點(diǎn)都在top的情況
            top.push_back(corners[i]);
        else
            bot.push_back(corners[i]);
    }
    corners.clear();

    if (top.size() == 2 && bot.size() == 2) 
    {
        //cout << "log" << endl;
        cv::Point2f tl = top[0].x > top[1].x ? top[1] : top[0];
        cv::Point2f tr = top[0].x > top[1].x ? top[0] : top[1];
        cv::Point2f bl = bot[0].x > bot[1].x ? bot[1] : bot[0];
        cv::Point2f br = bot[0].x > bot[1].x ? bot[0] : bot[1];


        corners.push_back(tl);
        corners.push_back(tr);
        corners.push_back(br);
        corners.push_back(bl);
    }
    else
    {
        corners = backup;
    }
}

第四步,四點(diǎn)法透射變換

我們拿到原圖信息區(qū)域四邊形的四個(gè)頂點(diǎn),現(xiàn)在我們還需要變換后圖像的四個(gè)頂點(diǎn)才可以實(shí)現(xiàn)投射變換。

求變換后四個(gè)頂點(diǎn)坐標(biāo)前我們還需要做的一件事就是,確定變換后的圖像尺寸。第一種方法就是人工指定,比如我直接規(guī)定好變換后的圖片大小是bbb*aaa。第二種方法就是,通過(guò)計(jì)算確定信息區(qū)域的尺寸,也就是說(shuō),信息區(qū)域有多大,我們變換后的圖像就有多大。

既然我們知道了四邊形的四個(gè)頂點(diǎn)了,那么我們可以直接求兩點(diǎn)的距離來(lái)確定四邊形的長(zhǎng)寬。變換后的圖像高度寬度可以這么確定:

int g_dst_hight;  //最終圖像的高度int g_dst_width; //最終圖像的寬度voidCalcDstSize(const vector<cv::Point2f>& corners){
    int h1 = sqrt((corners[0].x - corners[3].x)*(corners[0].x - corners[3].x) + (corners[0].y - corners[3].y)*(corners[0].y - corners[3].y));
    int h2 = sqrt((corners[1].x - corners[2].x)*(corners[1].x - corners[2].x) + (corners[1].y - corners[2].y)*(corners[1].y - corners[2].y));
    g_dst_hight = MAX(h1, h2);

    int w1 = sqrt((corners[0].x - corners[1].x)*(corners[0].x - corners[1].x) + (corners[0].y - corners[1].y)*(corners[0].y - corners[1].y));
    int w2 = sqrt((corners[2].x - corners[3].x)*(corners[2].x - corners[3].x) + (corners[2].y - corners[3].y)*(corners[2].y - corners[3].y));
    g_dst_width = MAX(w1, w2);
}

透射變換:

cv::Mat quad = cv::Mat::zeros(g_dst_hight, g_dst_width, CV_8UC3);
std::vector<cv::Point2f> quad_pts;
quad_pts.push_back(cv::Point2f(0, 0));
quad_pts.push_back(cv::Point2f(quad.cols, 0));
quad_pts.push_back(cv::Point2f(quad.cols, quad.rows));

quad_pts.push_back(cv::Point2f(0, quad.rows));

cv::Mat transmtx = cv::getPerspectiveTransform(corners, quad_pts);
cv::warpPerspective(source, quad, transmtx, quad.size());

所有關(guān)鍵步驟都已經(jīng)說(shuō)明完畢,運(yùn)行一下代碼,看看效果。

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

再拍一些其他圖片,看看處理效果

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能
OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能
OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能
OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

試一下帶有干擾背景的圖像,效果還是不錯(cuò)的

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

額外效果:二值化

有些時(shí)候還需要將一些文本或者證件弄成掃描模樣,那我們就加入二值化實(shí)現(xiàn)該效果。

Mat local,gray;
cvtColor(quad, gray, CV_RGB2GRAY);
int blockSize = 25;
int constValue = 10;
adaptiveThreshold(gray, local, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, blockSize, constValue);

imshow("二值化", local);

二值化效果挺好的

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能
OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能

源碼下載:

OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-481475.html

到了這里,關(guān)于OpenCV實(shí)現(xiàn)“全能掃描王”的圖像矯正功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 圖像處理的未來(lái):揭秘掃描全能王的AI驅(qū)動(dòng)創(chuàng)新

    圖像處理的未來(lái):揭秘掃描全能王的AI驅(qū)動(dòng)創(chuàng)新

    ???♂? 個(gè)人主頁(yè):@艾派森的個(gè)人主頁(yè) ???作者簡(jiǎn)介:Python學(xué)習(xí)者 ?? 希望大家多多支持,我們一起進(jìn)步!?? 如果文章對(duì)你有幫助的話, 歡迎評(píng)論 ??點(diǎn)贊???? 收藏 ??加關(guān)注+ 目錄 前言 一、底層技術(shù)-智能掃描引擎AI-Scan 圖像視覺(jué)矯正 去干擾技術(shù) 去陰影 去手指 去摩

    2024年02月12日
    瀏覽(17)
  • OpenCV圖像矯正技術(shù)基礎(chǔ)

    OpenCV圖像矯正技術(shù)是一種基于計(jì)算機(jī)視覺(jué)技術(shù)的圖像處理技術(shù),能夠?qū)⒁粡垐D像進(jìn)行矯正,使得圖像看起來(lái)更加規(guī)則、清晰。 OpenCV圖像矯正技術(shù)的實(shí)現(xiàn)思路: 1、獲取圖像:首先需要獲取要處理的圖像,對(duì)圖像進(jìn)行預(yù)處理,將圖像轉(zhuǎn)換成一種可用的格式,例如OpenCV中的Mat格式

    2024年02月13日
    瀏覽(19)
  • OpenCV圖像矯正

    OpenCV圖像矯正

    1. 針對(duì)邊緣比較明顯的圖片,使用基于輪廓提取的矯正方法。 基本步驟: 1)變?yōu)榛叶葓D; 2)Canny邊緣檢測(cè): Canny算法的基本思想是尋找一張圖片中灰度強(qiáng)度變化最強(qiáng)(梯度方向)的位置; 3)使用 OpenCV 的 findcontours()?提取輪廓(一個(gè)輪廓對(duì)應(yīng)一組點(diǎn)集); 4)根據(jù)輪廓求最

    2024年02月04日
    瀏覽(19)
  • OpenCV利用透視變換矯正圖像

    OpenCV利用透視變換矯正圖像

    案例:使用OpenCV將一張折射的圖片給矯正過(guò)來(lái) 實(shí)現(xiàn)步驟: 1.載入圖像 2.圖像灰度化 3.二值分割 4.形態(tài)學(xué)操作去除噪點(diǎn) 5.輪廓發(fā)現(xiàn) 6.使用霍夫直線檢測(cè),檢測(cè)上下左右四條直線(有可能是多條,但是無(wú)所謂) 7.繪制出直線 8.尋找與定位上下左右是條直線 9.擬合四條直線方程 1

    2024年02月06日
    瀏覽(20)
  • opencv圖像畸變矯正:源碼學(xué)習(xí)

    opencv圖像畸變矯正:源碼學(xué)習(xí)

    參考資料:相機(jī)標(biāo)定(4) 矯正畸變 undistort()和initUndistortRectifyMap() 背景: opencv提供了直接進(jìn)行畸變矯正的代碼,因在項(xiàng)目中需要使用畸變矯正,因此研究一下opencv中畸變矯正的相關(guān)接口與代碼,便于學(xué)習(xí)提升與二次開(kāi)發(fā)。 opencv在文檔中對(duì)相機(jī)標(biāo)定與畸變矯正的原理做了簡(jiǎn)單

    2024年02月10日
    瀏覽(42)
  • opencv對(duì)相機(jī)進(jìn)行畸變矯正,及從矯正后的圖像坐標(biāo)反求原來(lái)的對(duì)應(yīng)坐標(biāo)

    opencv對(duì)相機(jī)進(jìn)行畸變矯正,及從矯正后的圖像坐標(biāo)反求原來(lái)的對(duì)應(yīng)坐標(biāo)

    目前有個(gè)項(xiàng)目,需要用到熱成像相機(jī)。但是這個(gè)熱成像相機(jī)它的畸變比較厲害,因此需要用標(biāo)定板進(jìn)行標(biāo)定,從而消除鏡頭畸變。 同時(shí)需要實(shí)現(xiàn)用戶(hù)用鼠標(biāo)點(diǎn)擊校正后的畫(huà)面后,顯示用戶(hù)點(diǎn)擊位置的像素所代表的溫度。 另外熱成像sdk中還有個(gè)功能:選定一個(gè)rect,可以返回這

    2024年02月16日
    瀏覽(32)
  • 掃描全能王引領(lǐng)AI時(shí)代,助您輕松實(shí)現(xiàn)文檔數(shù)字化!

    掃描全能王引領(lǐng)AI時(shí)代,助您輕松實(shí)現(xiàn)文檔數(shù)字化!

    目錄 一、前言 1、什么是OCR 2、如何利用 Python 實(shí)現(xiàn)文字識(shí)別 二、掃描全能王介紹 1、什么是智能高清濾鏡 2、濾鏡主要技術(shù)點(diǎn) 3、在日常生活的表現(xiàn) 4、什么是AI-Scan 5、AI-Scan的特點(diǎn) 5.1、圖像視覺(jué)矯正 5.2、反光消除技術(shù) 5.3、去干擾技術(shù) 6、處理對(duì)比 三、總結(jié) 1、體驗(yàn)總結(jié) 2、對(duì)

    2024年02月11日
    瀏覽(22)
  • 《數(shù)字圖像處理-OpenCV/Python》連載(1)前言

    《數(shù)字圖像處理-OpenCV/Python》連載(1)前言

    本書(shū)京東優(yōu)惠購(gòu)書(shū)鏈接:https://item.jd.com/14098452.html 寫(xiě)作背景 編寫(xiě)本書(shū)的初衷,源自作者學(xué)習(xí)數(shù)字圖像處理的經(jīng)歷。 在創(chuàng)新實(shí)驗(yàn)班開(kāi)設(shè)的專(zhuān)業(yè)創(chuàng)新教育課程中,我選擇的是數(shù)字圖像處理方向。老師向我推薦的教材是岡薩雷斯的《數(shù)字圖像處理》。學(xué)習(xí)的開(kāi)始階段非常困難。教

    2024年02月11日
    瀏覽(161)
  • OpenCV C++ 圖像處理實(shí)戰(zhàn) ——《多尺度自適應(yīng)Gamma矯正的低照?qǐng)D像增強(qiáng)》
  • 使用python-opencv對(duì)雙目攝像頭進(jìn)行立體視覺(jué)圖像矯正,去畸變

    使用python-opencv對(duì)雙目攝像頭進(jìn)行立體視覺(jué)圖像矯正,去畸變

    ? ? ? ? 1、一張棋盤(pán)圖 ????????可以直接從opencv官方github下載,這是一個(gè)擁有10*7個(gè)格子的棋盤(pán),共有 9*6個(gè)角點(diǎn),每個(gè)格子24mm ,本文所使用的就是這一個(gè)棋盤(pán)。你需要將它打印在A4紙上用于后續(xù)使用。(也可以根據(jù)官方教程自行設(shè)置棋盤(pán)大小OpenCV: Create calibration pattern)

    2024年02月10日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包