图像柱面投影

article/2025/9/27 6:26:39

由于图像序列是实体景物在不同坐标系下的二维投影,直接对拍摄图像进行拼接无法满足视觉一致性,所以需要将待拼接的图像分别投影到一个标准的坐标系下,然后再进行图像的拼接。全景图生成系统可以采用圆柱体、立方体和球体等模型来实现。由于柱面坐标的变换比较简单并且投影图像与其投影到圆柱表面的位置无关,用其描述的柱面全景图像可在水平方向上满足360度环视,具有较好的视觉效果,因此被广泛采用。

 

原理:

把平面图像投影到圆柱的曲面上。

如下图,四边形GHEF表示待处理原图,投影之后,变成曲面JDILCK(黄色点标注)

                                            

                                                         图片来源:https://www.cnblogs.com/cheermyang/p/5431170.html

俯视图如下,DCE为待处理图像平面,FCG为投影所得曲面。

                         

                                                   图片来源:https://www.cnblogs.com/cheermyang/p/5431170.html

     设原图像宽W,高H,角度FOG为相机视场角度α(一般为45°,即PI/4),圆形半径(焦距)f 有tan 1/2α = W / (2 * f), 则有f = W / (2 * tan(α/2))。

    依次推算出,目标图像的宽(曲线FCG长)W‘ = f * α, 目标图像高H’不变, H‘ = H

 

方式一:以图像左上角坐标为原点

                                     

                                             图片来源:https://www.cnblogs.com/cheermyang/p/5431170.html

公式如下:

                                                                     

 

方式二:以图像中心为坐标原点,即(W/2, H/2),可以简计算公式

                                         

                                               图片来源:https://www.cnblogs.com/cheermyang/p/5431170.html

由于一般来说图像以左上角为坐标原点,所以在编写程序的时候最好采用以方式一。

下面使用OpenCV进行代码实现

1.直接根据方式一进行代码实现

/***Copyright (c) 2018 Young Fan.All Right Reserved.*Author: Young Fan*Date: 2018.9.30*OpenCV version: 3.4.3*IDE: Visual Studio 2017*Description:*/#include <iostream>
#include "opencv2/highgui/highgui.hpp"using namespace cv;
using namespace std;int main()
{Mat srcImage = imread("lena.jpg");Mat dstImage = Mat::zeros(srcImage.size(), CV_8UC3);int height = srcImage.rows; //原图像的高(即原图像矩阵行数)int width = srcImage.cols; //原图像的宽(即原图像矩阵列数)int centerX = width / 2; //图像中心横坐标int centerY = height / 2; //图像中心纵坐标double alpha = CV_PI / 4; //相机视角角度double f = width / (2 * tan(alpha / 2)); //焦距(圆的半径)//循环遍历for (int i = 0; i < srcImage.rows; i++){for (int j = 0; j < srcImage.cols; j++){//注意图像坐标与像素矩阵坐标的区别float theta = atan((j - centerX) / f);int pointX = f * alpha / 2 + f * theta; //用f * alpha / 2,两边缝隙会不均匀(只有右边有黑缝隙),用width / 2就均匀了int pointY = f * (i - centerY) / sqrt((j - centerX) * (j - centerX) + f * f) + centerY;//像素赋值dstImage.at<Vec3b>(pointY, pointX)[0] = srcImage.at<Vec3b>(i, j)[0];dstImage.at<Vec3b>(pointY, pointX)[1] = srcImage.at<Vec3b>(i, j)[1];dstImage.at<Vec3b>(pointY, pointX)[2] = srcImage.at<Vec3b>(i, j)[2];}}imshow("原图", srcImage);imshow("柱面投影效果图", dstImage);waitKey();return 0;
}

效果图:

如下图所示,效果图左右的黑色缝隙不对称。

首先说明一下,为啥会在上下左右出现黑色空隙?

     因为一张平面图像在进行柱面投影的时候,原图被转化为柱面图的形式显示在与原来尺寸一样的黑色背景图上,柱面投影效果图上有一部分像素点无法找到与原图与之对应坐标变换的点,所以会出现默认颜色为黑色的缝隙。按照直观的说法就是,原图转为柱面图像时在平面上被缩小了一些。

 那么为啥,只有右边有缝隙,而左边没有呢?

     这是因为推算的坐标变换公式所求出的柱面投影坐标,是在柱面上建立的坐标系,但是我们在代码实现并显示的时候,用的是一张平面图来呈现这个柱面图,也就是侧视图,所以要想得到左右对称图像,要在代码35行求横坐标的时候,将图像宽度要以原图的宽度为准,这样在显示的时候可以使左右缝隙更加对称。

                                      

 

2.改进代码,是左右缝隙对称

只用改进35行的代码就行,将“f * alpha / 2”改为“width / 2”,这样在显示的时候可以使左右缝隙更加对称。

/***Copyright (c) 2018 Young Fan.All Right Reserved.*Author: Young Fan*Date: 2018.9.30*OpenCV version: 3.4.3*IDE: Visual Studio 2017*Description:*/#include <iostream>
#include "opencv2/highgui/highgui.hpp"using namespace cv;
using namespace std;int main()
{Mat srcImage = imread("lena.jpg");Mat dstImage = Mat::zeros(srcImage.size(), CV_8UC3);int height = srcImage.rows; //原图像的高(即原图像矩阵行数)int width = srcImage.cols; //原图像的宽(即原图像矩阵列数)int centerX = width / 2; //图像中心横坐标int centerY = height / 2; //图像中心纵坐标double alpha = CV_PI / 4; //相机视角角度double f = width / (2 * tan(alpha / 2)); //焦距(圆的半径)//循环遍历for (int i = 0; i < srcImage.rows; i++){for (int j = 0; j < srcImage.cols; j++){//注意图像坐标与像素矩阵坐标的区别float theta = atan((j - centerX) / f);int pointX = width / 2 + f * theta; //注意这里用width / 2,用f * alpha两边缝隙不均匀(只有右边有黑缝隙)int pointY = f * (i - centerY) / sqrt((j - centerX) * (j - centerX) + f * f) + centerY;//像素赋值dstImage.at<Vec3b>(pointY, pointX)[0] = srcImage.at<Vec3b>(i, j)[0];dstImage.at<Vec3b>(pointY, pointX)[1] = srcImage.at<Vec3b>(i, j)[1];dstImage.at<Vec3b>(pointY, pointX)[2] = srcImage.at<Vec3b>(i, j)[2];}}imshow("原图", srcImage);imshow("柱面投影效果图", dstImage);waitKey();return 0;
}

效果图:

                                     

3.如果你不想要出现黑色缝隙,可以把左右黑色缝隙去除

          需要定义合适尺寸的目标图,然后就是目标图的列数(图像的横坐标)要左移,具体见下面代码。

/***Copyright (c) 2018 Young Fan.All Right Reserved.*Author: Young Fan*Date: 2018.10.6*OpenCV version: 3.4.3*IDE: Visual Studio 2017*Description:*/#include <iostream>
#include "opencv2/highgui/highgui.hpp"using namespace cv;
using namespace std;int main()
{Mat srcImage = imread("lena.jpg");int height = srcImage.rows; //原图像的高(即原图像矩阵行数)int width = srcImage.cols; //原图像的宽(即原图像矩阵列数)int centerX = width / 2; //图像中心横坐标int centerY = height / 2; //图像中心纵坐标double alpha = CV_PI / 4; //相机视角角度double f = width / (2 * tan(alpha / 2)); //焦距(圆的半径)//求左右黑色缝隙宽度int len = cvRound(width / 2 - f * alpha / 2); //cvRound:取整//定义合适的目标图Mat dstImage = Mat::zeros(srcImage.rows, width - 2 * len, CV_8UC3); //注意尺寸//循环遍历for (int i = 0; i < srcImage.rows; i++){for (int j = 0; j < srcImage.cols; j++){//注意图像坐标与像素矩阵坐标的区别float theta = atan((j - centerX) / f);int pointX = cvRound(width / 2 + f * theta); //注意这里用width / 2,用f * alpha / 2,两边缝隙会不均匀(只有右边有黑缝隙)int pointY = cvRound(f * (i - centerY) / sqrt((j - centerX) * (j - centerX) + f * f) + centerY);//像素赋值,此时要将列数(图像横坐标)往左移,与初始的黑色图像边缘对其,即pointX - lendstImage.at<Vec3b>(pointY, pointX - len)[0] = srcImage.at<Vec3b>(i, j)[0];dstImage.at<Vec3b>(pointY, pointX - len)[1] = srcImage.at<Vec3b>(i, j)[1];dstImage.at<Vec3b>(pointY, pointX - len)[2] = srcImage.at<Vec3b>(i, j)[2];}}imshow("原图", srcImage);imshow("柱面投影效果图", dstImage);waitKey();return 0;
}

去除黑色缝隙效果图:

                                   

参考博客:

https://www.cnblogs.com/cheermyang/p/5431170.html

https://blog.csdn.net/wd1603926823/article/details/49334229

                                  

 


http://chatgpt.dhexx.cn/article/RWJCYd0Q.shtml

相关文章

柱面投影介绍与python实现(一)

简介 本文主要介绍柱面投影变换,将这种变换用于图像处理,可以产生图像扭曲的效果,如下图所示,产生了将平面图像投影到了柱面上的视觉效果。博客最后给出了柱面投影的python实现,供读者参考。 数学原理 如下图所示,矩形GHEF为待处理的原图,投影到柱面上之后则变成了…

【Octave】柱面投影简析

我是分割线 在做全景拼接的时候&#xff0c;为了保持图片中的空间约束与视觉的一致性&#xff0c;需要做一定的预处理&#xff0c;可以是球面投影&#xff0c;柱面投影等。 如果仅仅是做水平方向的拼接&#xff0c;则做柱状投影就好了 一. 原理 把平面图像投影到圆柱的曲面上。…

拖库 洗库 撞库

间接转载地址: http://blog.csdn.net/daliaojie/article/details/42171177 一,背景: 用户数据泄露一直是如今互联网世界的一个焦点,从最近的京东撞库抹黑事件,到之前的CSDN,如家用户数据的泄露,服务商和黑客之间在用户数据这个舞台上一直在进行着旷日持久的攻防战。 对于…

分享一个验证码暴力撞库漏洞的案例

记录一个验证码暴力破解的案例&#xff0c;安全问题不容忽视呀。 某公司接到用户反馈&#xff0c;应用存在安全漏洞&#xff0c;通过技术手段可以在无手机情况下&#xff0c;获取验证码&#xff0c;直接修改密码成功。如果用户密码被他人修改成功&#xff0c;直接涉及到资产损…

深入浅出了解撞库攻击!

1. 撞库的原理和危害 “撞库”&#xff08;Credential Stuffing Attack&#xff09;在网络安全中是一个古老的概念&#xff0c;按中文的字面意思解读&#xff0c;就是“碰撞数据库”的意思。“碰撞”意味着碰运气&#xff0c;即不一定能成功&#xff1b;而“数据库”中往往存储…

使用 Burp Suite 暴力破解密码 撞库攻击 从0到1手摸手教学

说明 一个学习的过程 增加自己网络安全知识 切勿用于违法用途 设置密码尽量使用6位以上并规避简单数字组合、加强对同一ip的频繁访问次数限制、设置人机验证减小撞库攻击的危害 用到的工具&环境 本地环境 kali 2022 Burp Suite FireFox 靶机环境 一台服务器 CentO…

【htpwdScan 是一个HTTP暴力破解、撞库测试工具。】

htpwdScan 1.0 htpwdScan 是一个HTTP暴力破解、撞库测试工具。 安装 要求 python3.6 pip3 install requirements.txt特性 支持常见的认证模式&#xff1a;Basic/Digest/NTLM 等 支持对 GET / POST 参数进行暴力破解&#xff0c;支持使用占位符选定参数或参数的一部分 支持批…

MD5碰撞与撞库和题

MD5 相同的情况叫做“碰撞”&#xff0c;现在网络中已经出现了两个相同的 MD5 可执行文件&#xff0c;所以MD5现在已经被弃用了&#xff0c;发生碰撞的概率是1/&#xff08;2^128&#xff09;。 SHA-1 也会发生碰撞&#xff0c;但是几率比 MD5 小的多。 2004年&#xff0c;我…

拖库 洗库 撞库的概念

一&#xff0c;背景&#xff1a; 用户数据泄露一直是如今互联网世界的一个焦点&#xff0c;从最近的京东撞库抹黑事件&#xff0c;到之前的CSDN&#xff0c;如家用户数据的泄露&#xff0c;服务商和黑客之间在用户数据这个舞台上一直在进行着旷日持久的攻防战。 对于大多数用…

(云安全)拖库-洗库-撞库

一&#xff0c;背景&#xff1a; 用户数据泄露一直是如今互联网世界的一个焦点&#xff0c;从最近的京东撞库抹黑事件&#xff0c;到之前的CSDN&#xff0c;如家用户数据的泄露&#xff0c;服务商和黑客之间在用户数据这个舞台上一直在进行着旷日持久的攻防战。 对于大多数用户…

java解决撞库的问题_Web安全开发之验证码设计不当引发的撞库问题

感谢某电商平台安全工程师feiyu跟我一起讨论这个漏洞的修复。以往在安全测试的过程中后台经常存在验证码不失效果造成的撞库问题&#xff0c;甚至在一些银行或者电商的登录与查存页面同样存在这个问题&#xff0c;一旦造成撞库无论对用户账号的安全性还是网站的负载都是巨大的挑…

什么是撞库攻击,如何预防撞库攻击?

1. 撞库的原理和危害 “撞库”&#xff08;Credential Stuffing Attack&#xff09;在网络安全中是一个古老的概念&#xff0c;按中文的字面意思解读&#xff0c;就是“碰撞数据库”的意思。“碰撞”意味着碰运气&#xff0c;即不一定能成功&#xff1b;而“数据库”中往往存储…

撞库详解

撞库攻击是如今最常见的攻击&#xff0c;给企业带来巨大威胁。撞库带来的威胁往往不是直接的&#xff0c;但是由此造成的信息泄露以及进一步的渗透与攻击会更为严重。Akamai的报告显示&#xff0c;2018年五月到十二月期间&#xff0c;共发生了约280亿次撞库攻击&#xff0c;其中…

mysql暴力撞库与弱密码检测

暴力撞库与弱密码检测 最近在生产数据库上碰到了一个问题&#xff0c;觉得挺有意思&#xff0c;总结出来和大家分享下。 关于暴力撞库和弱密码检测。 相信使用数据库的大家应该都不陌生&#xff0c;暴力撞库&#xff0c;简单通俗的讲通过一堆生成的密码&#xff0c;然后用默认…

倾家荡产、隐私全无?独家揭秘撞库攻击!

1. 撞库的原理和危害 “撞库”&#xff08;Credential Stuffing Attack&#xff09;在网络安全中是一个古老的概念&#xff0c;按中文的字面意思解读&#xff0c;就是“碰撞数据库”的意思。“碰撞”意味着碰运气&#xff0c;即不一定能成功&#xff1b;而“数据库”中往往存储…

撞库是什么

撞库&#xff08;Credential Stuffing&#xff09;是黑客通过收集互联网已泄露的用户和密码信息&#xff0c;生成对应的字典表&#xff0c;尝试批量登录其他网站后&#xff0c;得到一系列可以登录的用户。很多用户在不同网站使用的是相同的帐号密码&#xff0c;因此黑客可以通过…

什么是撞库及撞库攻击的基本原理

6月26日晚&#xff0c;我国大型聊天软件QQ出现了大规模盗号情况&#xff0c;而且是在QQ号本人在线时出现了被盗情况。 6月27日中午&#xff0c;腾讯QQ发布声明称&#xff1a;6月26日晚上10点左右&#xff0c;收到部分用户反馈QQ号码被盗。QQ安全团队高度重视并立即展开调查&am…

企业微信如何关联小程序?

我们在日常使用微信时&#xff0c;经常会用到小程序功能&#xff0c;直接从微信中打开第三方页面&#xff0c;很是方便&#xff0c;那么自从企业微信与微信打通之后&#xff0c;我们该如何将小程序与企业微信联系起来使用呢&#xff1f; 其实&#xff0c;在企业微信中&#xf…

企业微信登录报错:应用程序无法正常启动(0xc0000142);Win10应用程序无法正常启动0xc0000142错误的解决方法

企业微信登录报错&#xff0c;有时候要点击多次才能登陆。 解决办法&#xff1a;创建一个文本&#xff0c;把下面一段复制进去&#xff0c;文本后缀改成.bat&#xff0c;启动运行一下即可。 sc stop NSFFileCtl sc config NSFFileCtl start disabled pause 如下图&#xff1a…

企业微信小程序从开发调试到发布的全流程

企业微信小程序和普通微信小程序两者的关系 可以理解为企业微信小程序就是把普通小程序丢进了企业微信这个app里运行&#xff0c;企业微信小程序的发布依赖普通微信&#xff0c;需要先按照普通微信的发布流程进行发布&#xff0c;再去企业微信平台进行绑定小程序到工作台。 企…