opencv 截取任意四边形区域的图像
截取任意四边形区域的图像。
mask就是结果。
需要定义四边形区域,分别是 tl, tr, bl, br
std::map<int, std::set<int>> generateBorders(const std::vector<cv::Point> & vecPts)
{
std::map<int, std::set<int>> borders;
cv::Point tl(vecPts[0]), tr(vecPts[1]), bl(vecPts[2]), br(vecPts[3]); // tl to tr
double K = double(tl.y-tr.y) / (tl.x - tr.x);
for (int i = tl.x; i < tr.x; ++i)
borders[i].insert(cvRound(-K*(tl.x - i) + tl.y)); // tr to br
if (tr.x != br.x)
{
K = double(tr.y - br.y) / (tr.x - br.x);
for (int i = tr.x; i < br.x; ++i)
borders[i].insert(cvRound(-K*(tr.x - i) + tr.y));
} // br to bl
K = double(br.y - bl.y) / (br.x - bl.x);
for (int i = bl.x; i < br.x; ++i)
borders[i].insert(cvRound(-K*(br.x - i) + br.y)); // bl to tl
if (bl.x != tl.x)
{
K = double(bl.y - tl.y) / (bl.x - tl.x);
for (int i = tl.x; i < bl.x; ++i)
borders[i].insert(cvRound(-K*(bl.x - i) + bl.y));
} for (auto it = borders.begin(); it!=borders.end(); ++it)
{
if ((*it).second.size() == 2)
continue; std::set<int> newone = { *(*it).second.begin(), *(--(*it).second.end())};
(*it).second.swap(newone);
} #ifdef DEBUG_CODE
cv::Mat disp = cv::imread("1111.PNG", CV_LOAD_IMAGE_COLOR); for (auto it = borders.begin(); it != borders.end(); ++it)
{
cv::circle(disp, cv::Point((*it).first, *(*it).second.begin()), 1, cv::Scalar(255, 255, 0), -1);
cv::circle(disp, cv::Point((*it).first, *(--(*it).second.end())), 1, cv::Scalar(0, 255, 255), -1); } cv::circle(disp, tl, 2, cv::Scalar(0, 0, 255), -1);
cv::circle(disp, tr, 2, cv::Scalar(0, 0, 255), -1);
cv::circle(disp, bl, 2, cv::Scalar(0, 0, 255), -1);
cv::circle(disp, br, 2, cv::Scalar(0, 0, 255), -1);
#endif // DEBUG_CODE return borders;
} cv::Mat generateMask(const cv::Mat & src,
const std::vector<cv::Point> & vecPts)
{
cv::Mat mask = cv::Mat::zeros(src.size(), CV_8UC1); cv::Point tl(vecPts[0]), tr(vecPts[1]), bl(vecPts[2]), br(vecPts[3]);
std::map<int, std::set<int>> borders = generateBorders(vecPts); int minX = std::min(tl.x, bl.x),
maxX = std::max(tr.x, br.x),
minY = std::min(tl.y, tr.y),
maxY = std::max(bl.y, br.y); uchar minZ = std::min(src.at<uchar>(tl), src.at<uchar>(tr));
minZ = std::min(minZ, src.at<uchar>(bl));
minZ = std::min(minZ, src.at<uchar>(br)); for (size_t j= minY; j<maxY; ++j)
{
const uchar* pS = src.ptr<uchar>(j);
uchar* pM = mask.ptr<uchar>(j); for (size_t i = minX; i < maxX; ++i)
{
// in the region.
if (*borders[i].begin() < j && j < *(++borders[i].begin()))
{
pM[i] = pS[i];
}
}
} return mask; }
opencv 截取任意四边形区域的图像的更多相关文章
- OpenCV计算机视觉学习(2)——图像算术运算 & 掩膜mask操作(数值计算,图像融合,边界填充)
在OpenCV中我们经常会遇到一个名字:Mask(掩膜).很多函数都使用到它,那么这个Mask到底是什么呢,下面我们从图像基本运算开始,一步一步学习掩膜. 1,图像算术运算 图像的算术运算有很多种,比 ...
- OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)
PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...
- OpenCV:二值图像连通区域分析与标记算法实现
http://blog.csdn.net/cooelf/article/details/26581539?utm_source=tuicool&utm_medium=referral Open ...
- OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 下面 ...
- OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...
- OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...
- OpenCV中IplImage图像格式与BYTE图像数据的转换
最近在将Karlsruhe Institute of Technology的Andreas Geiger发表在ACCV2010上的Efficent Large-Scale Stereo Matchin ...
- HTML <map> 标签-创建带有可点击区域的图像映射
定义和用法 定义一个客户端图像映射.图像映射(image-map)指带有可点击区域的一幅图像. 所有主流浏览器都支持 <map> 标签. 注释:area 元素永远嵌套在 map 元素内部. ...
- HTML <area> 标签 带有可点击区域的图像映射(图像映射指的是带有可点击区域的图像)
例子: <img src="planets.gif" width="145" height="126" alt="Plane ...
随机推荐
- SQL注入神器———Sqlmap!
Sqlmap 开源,python编写 支持5种SQL注入检测技术: 1.基于布尔的注入检测 2.基于时间的注入检测 3.基于错误的注入检测 4.基于UNION联合查询的检测 5.基于堆叠查询的检测 支 ...
- acwing 600. 仰视奶牛
题目地址 https://www.acwing.com/problem/content/description/602/ 约翰有N头奶牛,编号为1到N. 现在这N头奶牛按编号从小到大的顺序站成了一排 ...
- x86-64数据格式、通用寄存器与操作数格式
x86-64数据格式.通用寄存器与操作数格式 数据格式 Intel用术语"字(word)"表示16位数据类型,32位为"双字(double words)", ...
- Saiku上线部署准备(三十)
Saiku上线部署准备 零零散散琢磨了快5个月了,终于快要上线了哈哈哈哈哈..... 激动!!! 以下是本地打包编译saiku至部署到服务器上使用的完整步骤哦 saiku部署到服务器 源码编译需要注 ...
- win10下mysql5.7的安装与配置
Win10下MySql5.7的安装与配置 下载 官网下载地址 选择免安装版即可, 解压 将下载的压缩包解压到你想要放置MySQL的目录,避免中文空格. 示例:D:\devtools\mysql-5.7 ...
- 数据库——SQL-SERVER练习(2)连接与子查询
一.实验准备 1.复制实验要求文件及“CREATE-TABLES.SQL”文件, 粘贴到本地机桌面. 2.启动SQL-SERVER服务. 3. 运行查询分析器, 点击菜单<文件>/< ...
- this泛指函数的上下文
this泛指函数的上下文 当前函数运行的类型上下文.
- Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之三 || Swagger的使用 3.1
本文梯子 本文3.0版本文章 常见问题 1.Bug调试 2.经常有小伙伴遇到这个错误 3.路由重载 一.为什么使用Swagger 二.配置Swagger服务 1.引用Nuget包 2.配置服务 3.启 ...
- C# virtual 和 abstract 区别
Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例 ...
- JavaScript之找LHS查询和RHS查询
LHS和RHS,当变量出现在赋值操作的左侧时进行LHS 查询,出现在右侧时进行RHS 查询. LHS 查询是试图找到变量的容器本身,从而可以对其赋值. RHS 理解成retrieve his sour ...