【计算机视觉基础】IPM
IPM
逆透视变换的整体过程:
灭点的求解
假设Zc为1,
消失点可以认为是空间直线上无穷远处的点投影在图像上所成的像点。对于空间中某一直线L,方向为(dx,dy,dz),给定直线上坐标(ax,ay,az),所以直线上任一点A可以表示为:
当趋于无穷时可以得到
从而得到消失点的坐标。
注:逆透视变换的范围不能到达消失点,否则不能还原。
code
#if 0 void xyp2ipmp(cv::Mat& xyp, cv::Mat& ipmp, cv::Mat& xylim, Size& sz){ //xylimist_[0]-latteral/xylimist_[1]-longitudinal... //ipmp-row0-cols-latteral/ipmp-row1-rows-longitudinal... double xmin = 0, xmax = 0, ymin = 0, ymax = 0; minMaxLoc(xylim.row(0), &xmin, &xmax); minMaxLoc(xylim.row(1), &ymin, &ymax); double stepcol = (xmax - xmin) / sz.width; double steprow = (ymax - ymin) / sz.height; cv::Mat tempx = cv::Mat::ones(1, xyp.cols, CV_64FC1) * xmin; cv::Mat tempy = cv::Mat::ones(1, xyp.cols, CV_64FC1) * ymax; ipmp = cv::Mat::zeros(2, xyp.cols, CV_64FC1); ipmp.rowRange(0, 1) = ( xyp.rowRange(0, 1) - tempx ) / stepcol; ipmp.rowRange(1, 2) = ( tempy - xyp.rowRange(1, 2) ) / steprow; for (int i = 0; i < xyp.cols; i++ ) { double y = ipmp.at<double>(1, i); if( y > ymax){ ipmp.at<double>(1, i) = ymax; } } } #endif
code
#if 0 //IPM-parameters... double left_upper_x = 1;//left double left_upper_y = 330;//top-greater than 320... double right_down_x = 1280;//right... double right_down_y = 720;//bottom... double uvlimist[8] = { left_upper_x, right_down_x, left_upper_x, right_down_x, left_upper_y, left_upper_y, right_down_y, right_down_y }; cv::Mat uvlmt = cv::Mat(2, 4, CV_64FC1, uvlimist); //I2G cv::Mat xylimit; imagetoground(uvlmt, xylimit, h, roll, pitch, camera_param_KK); //G2I cv::Mat uvgd; cv::Size sz = cv::Size(PROB_W, PROB_H);//Size(srcimage.cols, srcimage.rows) groundtoimage(xylimit, uvgd, sz, h, roll, pitch, camera_param_KK ); #endif
code
#if 1 //IPM... cv::Mat outimage, coord; src2ipm( prob, uvgd, outimage, coord, sz, h, roll, pitch, camera_param_KK ); outimage.convertTo(outimage, CV_8UC1); cv::Mat ipm3 = cv::Mat::zeros(PROB_H, PROB_W, CV_8UC3); cv::cvtColor(outimage, ipm3, COLOR_GRAY2BGR); // //cv::Mat uvp = cv::Mat::zeros(2, probp.size(), CV_8UC1); cv::Mat uvp = cv::Mat::zeros(2, probp.size(), CV_64FC1);//data-type... for (unsigned int i = 0; i <probp.size(); i++ ) { uvp.at<double>(0, i) = probp[i].x;//cols-width. uvp.at<double>(1, i) = probp[i].y;//rows-height. //std::cout << uvp.at<double>(0, i) << "-----" << probp[i].x <<std::endl; //std::cout << uvp.at<double>(1, i) << "-----" << probp[i].y <<std::endl; } cv::Mat ipmps, xyp; //std::cout << "uvp:" << uvp << std::endl; imagetoground(uvp, xyp, h, roll, pitch, camera_param_KK); xyp2ipmp(xyp, ipmps, xylimit, sz); ipmps.convertTo(ipmps, CV_32SC1); for (unsigned int i = 0; i <probp.size(); i++ ) { cv::Point ipmp; ipmp.x = ipmps.at<int>(0, i); ipmp.y = ipmps.at<int>(1, i); if (plabel[i] == 1)//-barrier { cv::circle(ipm3, ipmp, 3, cv::Scalar(240, 32, 160), -1); // //cv::putText(orig, std::to_string(i), pt, CV_FONT_NORMAL, 0.1, cv::Scalar(255, 255, 255)); } else if (plabel[i] == 0)//-undifined { cv::circle(ipm3, ipmp, 3, cv::Scalar(255, 255, 0), -1); // //cv::putText(orig, std::to_string(i), pt, CV_FONT_NORMAL, 0.1, cv::Scalar(255, 255, 255)); } } cv::imshow("ipmp", ipm3); cv::waitKey(1);//unit-ms. sprintf(output_path,"./ipmp/00000%05d.png",cnt); cv::imwrite(output_path, ipm3); #endif
参考
3. matlab_github;
完
各美其美,美美与共,不和他人作比较,不对他人有期待,不批判他人,不钻牛角尖。
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2018-11-14 【opencv基础】cv::Mat::type() 返回值