gpt4 book ai didi

c++ - 使用 Opencv 改变视角

转载 作者:行者123 更新时间:2023-11-28 07:28:46 24 4
gpt4 key购买 nike

我正在做一个项目,在这个项目中我使用了棋盘,我面临的问题是,当我识别出棋盘时,我想裁剪包含它的框架部分并将其“笔直” ,因为我正在使用 cv::warpPerspective 函数,下面是我的代码和我得到的结果:

int main (){
cv::Size board(6,4);
cv::Mat src,result,quad,transformationMatrix;
std::vector<cv::Point2f> imageCorners;
std::vector<cv::Point2f> top, bot;
std::vector<cv::Point2f> not_a_rect_shape;
cv::VideoCapture cap(0);
char fileName[20] = "MYROI";
int index =0;
int key = 0 ;
cap >> src;
while ( key != 27){
cap >> src;
if(cv::findChessboardCorners(src,board,imageCorners,CV_CALIB_CB_FILTER_QUADS)){
int xMin =imageCorners.at(0).x ,xMax = imageCorners.at(0).x;
int yMin = imageCorners.at(0).y, yMax =imageCorners.at(0).y;
for (int i = (imageCorners.size()-1) ; i>0;i--){
if(xMin > imageCorners.at(i-1).x)
xMin = imageCorners.at(i-1).x;
if(xMax < imageCorners.at(i-1).x)
xMax = imageCorners.at(i-1).x;
if(yMin > imageCorners.at(i-1).y)
yMin = imageCorners.at(i-1).y;
if(yMax < imageCorners.at(i-1).y)
yMax = imageCorners.at(i-1).y;
}
cv::Rect myroi(xMin-5,yMin-5,(xMax-xMin)+5,(yMax-yMin)+5);
if ( myroi.area() > 0){
cv::imshow("ROI",(src)(myroi));
result = (src)(myroi);
not_a_rect_shape.clear();
not_a_rect_shape.push_back(imageCorners[0]);
not_a_rect_shape.push_back(imageCorners[board.height-1]);
not_a_rect_shape.push_back(imageCorners[board.area()-board.height-1]);
not_a_rect_shape.push_back(imageCorners[board.area()-1]);
std::vector<cv::Point2f> approx;
cv::approxPolyDP(cv::Mat(not_a_rect_shape),approx,cv::arcLength(cv::Mat(not_a_rect_shape),true)*0.02,true);
if (approx.size()!=4){
std::cout << " Not quadrilateral!"<<std::endl;

not_a_rect_shape.clear();
approx.clear();

not_a_rect_shape.push_back(imageCorners[0]);
not_a_rect_shape.push_back(imageCorners[board.width-1]);
not_a_rect_shape.push_back(imageCorners[board.area()-board.width-1]);
not_a_rect_shape.push_back(imageCorners[board.area()-1]);
cv::approxPolyDP(cv::Mat(not_a_rect_shape),approx,cv::arcLength(cv::Mat(not_a_rect_shape),true)*0.02,true);
}

// center
cv::Point2f center(0,0);
for (int i = 0 ; i <not_a_rect_shape.size(); i++)
center+= not_a_rect_shape[i];
center *=( 1./not_a_rect_shape.size()); // the center position

top.clear();
bot.clear();
// ordering the 4 points
for (int i = 0; i < not_a_rect_shape.size(); i++){
if (not_a_rect_shape[i].y < center.y)
top.push_back(not_a_rect_shape[i]);
else
bot.push_back(not_a_rect_shape[i]);
}
std::cout << center << std::endl;
if(top.size()== 2 && bot.size()==2){
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];
not_a_rect_shape.clear();
not_a_rect_shape.push_back(tl);
not_a_rect_shape.push_back(tr);
not_a_rect_shape.push_back(br);
not_a_rect_shape.push_back(bl);

// Define the destination image
quad = cv::Mat::zeros(300, 220, CV_8UC3);
//quad = cv::Mat::zeros(result.rows,result.cols,CV_8UC3);
// Corners of the destination image
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));
transformationMatrix= cv::getPerspectiveTransform(not_a_rect_shape, quad_pts);
cv::warpPerspective(src, quad, transformationMatrix, quad.size()/*perspectiveSize*/,1);
cv::imshow("quadrilateral", quad);
cv::imwrite("result.jpg",result);
cv::imwrite("quadrilateral.jpg",quad);

}

}
}
cv::imshow("src",src);
key = cv::waitKey(10);
}

这是获得 ROI 的示例:

quadrilateral

这是改变视角后的样子:

result

假设这是我所期望的(这个大小无关紧要):

expected

知道如何解决这个问题吗?

最佳答案

我正在使用下一个代码片段来解决此类问题:

...
// Create a column vector with the coordinates of each point (on the field plane)
cv::Mat xField;
xField.create(4, 1, CV_32FC2);
xField.at<Point2f>(0) = ( Pts[0] );
xField.at<Point2f>(1) = ( Pts[1] );
xField.at<Point2f>(2) = ( Pts[2] );
xField.at<Point2f>(3) = ( Pts[3] );

// same thing for xImage but with the pixel coordinates instead of the field coordinates, same order as in xField
cv::Mat xImage;
xImage.create(4, 1, CV_32FC2);
xImage.at<Point2f>(0) = ( cv::Point2f(0, 0) );
xImage.at<Point2f>(1) = ( cv::Point2f(400, 0) );
xImage.at<Point2f>(2) = ( cv::Point2f(400, 600) );
xImage.at<Point2f>(3) = ( cv::Point2f(0, 600) );

// Compute the homography matrix
cv::Mat H = cv::findHomography(xField,xImage );
xField.release();
xImage.release();

Mat warped;
warpPerspective(frame,warped,H,Size(400,600));
H.release();
...

此代码将从多边形 xField 获取图像并将其放入 xImage(此处为矩形 0,0,400,600)。

你错了:改变这个

not_a_rect_shape.push_back(tl);
not_a_rect_shape.push_back(tr);
not_a_rect_shape.push_back(br);
not_a_rect_shape.push_back(bl);

为此

not_a_rect_shape.push_back(imageCorners[0]);
not_a_rect_shape.push_back(imageCorners[board.area()-board.width]);
not_a_rect_shape.push_back(imageCorners[board.area()-1]);
not_a_rect_shape.push_back(imageCorners[board.width-1]);

关于c++ - 使用 Opencv 改变视角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18181012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com