截取任意四边形区域的图像。

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 截取任意四边形区域的图像的更多相关文章

  1. OpenCV计算机视觉学习(2)——图像算术运算 & 掩膜mask操作(数值计算,图像融合,边界填充)

    在OpenCV中我们经常会遇到一个名字:Mask(掩膜).很多函数都使用到它,那么这个Mask到底是什么呢,下面我们从图像基本运算开始,一步一步学习掩膜. 1,图像算术运算 图像的算术运算有很多种,比 ...

  2. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  3. OpenCV:二值图像连通区域分析与标记算法实现

    http://blog.csdn.net/cooelf/article/details/26581539?utm_source=tuicool&utm_medium=referral Open ...

  4. OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 下面 ...

  5. OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...

  6. OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...

  7. OpenCV中IplImage图像格式与BYTE图像数据的转换

    最近在将Karlsruhe Institute of Technology的Andreas Geiger发表在ACCV2010上的Efficent Large-Scale Stereo Matchin ...

  8. HTML <map> 标签-创建带有可点击区域的图像映射

    定义和用法 定义一个客户端图像映射.图像映射(image-map)指带有可点击区域的一幅图像. 所有主流浏览器都支持 <map> 标签. 注释:area 元素永远嵌套在 map 元素内部. ...

  9. HTML <area> 标签 带有可点击区域的图像映射(图像映射指的是带有可点击区域的图像)

    例子: <img src="planets.gif" width="145" height="126" alt="Plane ...

随机推荐

  1. Quasar framework 配置vue apollo

    Quasar 整合 vue-apollo 确保你已经知道quasar 和 vue apollo 在quasar中使用vue apollo客户端时出现的一点小问题 在quasar项目中使用vue-apo ...

  2. csrf攻击与csrf防御

    CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站 ...

  3. Python连载42-异步协程函数

    一.  asyncio 1.python3.4开始引入标准库之中,内置对异步io的支持 2.asyncio本身是一个消息循环 3.步骤: (1)创建消息循环 (2)把协程导入 (3)关闭 4.举例: ...

  4. source vimrc的时候报错:.vimrc:1: command not found: syntax

    vim的配置如下: 1 syntax enable //语法高亮 2 set number //显示行号 3 set cursorline //突出显示当前行 4 set ruler //打开状态栏标 ...

  5. for循环用了那么多次,但你真的了解它么?

    一.基础的for循环 0.使用while也是一种循环方式,此处探究for相关的循环,就不做拓展了. 1.遍历数组的时候,初学时是使用的如下样式的for循环: for(int i=0;i<a.le ...

  6. SpringMVC日期类型接收空值异常问题

    最近遇到SpringMVC写个controller类,传一个空串的字符类型过来,正常情况是会自动转成date类型的,因为数据表对应类类型就是date的 解决方法是在controller类的后面加个注解 ...

  7. C++ day01-C++的函数和对象

    C++的函数和对象 1.1 1 混合型语言 c++以.cpp为文件扩展名,有且只有一个名为main的主函数,因保留了这个面向过程的主函数,所以被称为混合语言 2 注释方式 . C++的注释方式有两种, ...

  8. C++入门到理解阶段二基础篇(2)——C++注释、变量、常量、关键字、标识符

    目录 1.注释 注释作用 注释的方式 2.变量 变量基本知识 定义变量 3.常量 常量基本知识 整数常量 浮点常量 布尔常量 字符常量 字符串常量 常量定义 使用 #define 预处理器. 使用 c ...

  9. Gallery -- 横向不断滚动 demo

    <%@ Page Language="C#" AutoEventWireup="true" %> <!DOCTYPE html> < ...

  10. Python里三个最高逼格的调试神器

    调试是开发过程中不可避免的一个环节,在Python中我们使用print.logging.assert等方法进行调试既简单又实用,但毕竟有其局限性.今天这篇文章为大家带来三个工具,其中有Python的内 ...