1、目前效果最好的乙個: 但還是紙牌能檢測出來
2、下面將我修改執行成功的**貼出,至於優化,提高識別四邊形準確度,還需要繼續研究。
//透視變換,檢測四邊形,有時候容易檢測不出
//但目前效果最好的就是該程式
#include "stdafx.h"
#include "core/core.hpp"
#include
#include
#include
#include
cv::point2f center(0, 0);
//求四個頂點的座標
// 類函式,point2f為乙個類物件
cv::point2f computeintersect(cv::vec4i a, cv::vec4i b)
else
return cv::point2f(-1, -1);
}//確定四個點的中心線
void sortcorners(std::vector
& corners, cv::point2f center)
}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.clear();
//注意以下存放順序是順時針,當時這裡出錯了,如果想任意順序下文開闢的四邊形矩陣注意對應
corners.push_back(tl);
corners.push_back(tr);
corners.push_back(br);
corners.push_back(bl);
}// 演算法流程:先彩色轉灰度,然後模糊求canny邊緣,再用hough檢測直線,
// 求出四線交點,利用opencv自帶的求透視矩陣的函式求出透視矩陣,
// 然後利用透視矩陣轉換源影象所需的四邊形,效果圖後續見:
int main()
cv::mat bw;
//彩色轉灰度
cv::cvtcolor(src, bw, cv_bgr2gray);
cv::namedwindow("gray_src",0);
imshow("gray_src", bw);
//模糊
cv::blur(bw, bw, cv::size(3, 3));
cv::namedwindow("blur", 0);
imshow("blur", bw);
//邊緣檢測
cv::canny(bw, bw, 100, 100, 3);
cv::namedwindow("cannyblur", 0);
imshow("cannyblur", bw);
//hough檢測直線
std::vector
lines;
cv::houghlinesp(bw, lines, 1, cv_pi / 180, 70, 30, 10);
//1畫素分辨能力 1度的角度分辨能力 >70可以檢測成連線 30是最小線長
//在直線l上的點(且點與點之間距離小於maxlinegap=10的)連成線段,然後這些點全部刪除,並且記錄該線段的引數,就是起始點和終止點
//needed for visualization only//這裡是將檢測的線調整到延長至全屏,即射線的效果,其實可以不必這麼做
for (unsigned
int i = 0; i0] = 0;
lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2])* -v[0] + v[1];
lines[i][2] = src.cols;
lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2])*(src.cols - v[2]) + v[3];
}std::vector
corners;//線的交點儲存
for (unsigned
int i = 0; ifor (unsigned
int j = i + 1; jif (pt.x >= 0 && pt.y >= 0)}}
std::vector
//檢測是否是四邊形,很多檢測不到
//get mass center
for (unsigned
int i = 0; i < corners.size(); i++)
center *= (1. / corners.size());
sortcorners(corners, center);
cv::mat dst = src.clone();
//draw lines
for (unsigned
int i = 0; i0], v[1]), cv::point(v[2], v[3]), cv_rgb(0, 255, 0)); //目標版塊畫綠線
}//draw corner points
cv::circle(dst, corners[0], 3, cv_rgb(255, 0, 0), 2);
cv::circle(dst, corners[1], 3, cv_rgb(0, 255, 0), 2);
cv::circle(dst, corners[2], 3, cv_rgb(0, 0, 255), 2);
cv::circle(dst, corners[3], 3, cv_rgb(255, 255, 255), 2);
//draw mass center
cv::circle(dst, center, 3, cv_rgb(255, 255, 0), 2);
cv::mat quad = cv::mat::zeros(300, 220, cv_8uc3);//設定校正過的從320*240變為300*220
//corners of the destination image
std::vector
quad_pts;
quad_pts.push_back(cv::point2f(0, 0));
quad_pts.push_back(cv::point2f(quad.cols, 0));//(220,0)
quad_pts.push_back(cv::point2f(quad.cols, quad.rows));//(220,300)
quad_pts.push_back(cv::point2f(0, quad.rows));
// get transformation matrix
cv::mat transmtx = cv::getperspectivetransform(corners, quad_pts); //求源座標系(已畸變的)與目標座標系的轉換矩陣
cv::warpperspective(src, quad, transmtx, quad.size());
cv::namedwindow("src", 0);
cv::imshow("src", src);
cv::namedwindow("image", 0);
cv::imshow("image", dst);
cv::namedwindow("quadrilateral", 0);
cv::imshow("quadrilateral", quad);
cv::waitkey();
return
0;}
執行結果 opencv 透視變換
cv getperspectivetransform c 介面其呼叫形式如下 point2f src 4 dst 4 src 0 x 賦值 cv mat cv getperspectivetransform 返回透視變換矩陣 const cv point2f src,源影象四個頂點座標 點陣列 co...
OpenCV 透視變換矯正
演示結果參考 功能實現 執行程式,會顯示的尺寸,按回車鍵後,依次點選需矯正的的左上 右上 左下 右下角,並能顯示其座標,結果彈出矯正後的,如圖上的pic2對話方塊。可以繼續選擇四個點進行實驗,按下字元 q 後退出。如下 注 圖中的11.jpg自己選取放到該程式目錄下。使用滑鼠在原影象上選取感興趣區域...
opencv2413 透視變換
因為專案需要,開始接觸透視變換的原理和實現。請注意透視變換與仿射變換的區別。其核心思想是 找到原影象中的四個點,確定變換之後的四個點位置,分別對應,然後呼叫函式,計算出透視變換的4 4矩陣。最後,利用得到的透視變換矩陣,根據原影象,即可計算出變換之後的影象。話不多說,先上一些 開發環境opencv2...