main.cpp

cv::Mat CropImage(cv::Mat& src, cv::RotatedRect& rotatedRect);
cv::Mat MaxBoxSelectionRotatedRect(cv::Mat& src, cv::RotatedRect& ret); int main()
{
#if 1
cv::VideoCapture capture;
cv::Mat rawData;
cv::Mat ROI;
cv::namedWindow("Show", cv::WINDOW_NORMAL);
cv::namedWindow("ROI", cv::WINDOW_AUTOSIZE);
capture.open(0);
capture.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
#if 0
capture.set(cv::CAP_PROP_FRAME_WIDTH, 3264);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, 2448);
#endif
cv::RotatedRect rotatedRect;
while (capture.isOpened())
{
capture >> rawData;
if (rawData.empty()){break;}
/******************************算法处理*******************************************/
#if 1
if (cv::waitKey(1) == Esc)
{
cv::imwrite("640x480.jpg", rawData);
}
cv::Mat src = rawData.clone();
src = MaxBoxSelectionRotatedRect(src, rotatedRect);
ROI = CropImage(rawData, rotatedRect);
#else
ROI = ImageColorMode(rawData, 3);
#endif /*********************************************************************************/
cv::imshow("ROI", ROI);
cv::imshow("Show", src);
//退出循环
if (cv::waitKey(1) == Esc)
{
cv::imwrite("640x480.jpg", rawData);
break;
}
}
#else #endif
pause();
return 0;
}
cv::Mat CropImage(cv::Mat& src,cv::RotatedRect& rotatedRect)
{
//std::cout << rotatedRect.size.width << "x" << rotatedRect.size.height << std::endl;
//定义框架边框边距像素大小以及参照物像素大小
const int pixel = 10;
const int defaultPixel = 5000000; //获取4个最小矩形四个顶点
cv::Point2f pts[4];
rotatedRect.points(pts); //获取最小矩形中心点
cv::Point2f center = cv::Point2f((pts[0].x + pts[2].x) / 2, (pts[0].y + pts[2].y) / 2);
//获取旋转角度
double angle = rotatedRect.angle; std::cout << "angle:" << angle << std::endl;
#if 0
//获取最小矩形长和宽 获取该参数可实现长方形矩形始终水平放置
int lineWidth = sqrt((pts[1].y - pts[0].y)*(pts[1].y - pts[0].y) + (pts[1].x - pts[0].x)*(pts[1].x - pts[0].x));
int lineHeight = sqrt((pts[3].y - pts[0].y)*(pts[3].y - pts[0].y) + (pts[3].x - pts[0].x)*(pts[3].x - pts[0].x));
#endif //
cv::Rect roi;
//边距
int margin = pixel * src.cols * src.rows / defaultPixel;
//宽
roi.width = rotatedRect.size.width - margin * 2;
//高
roi.height = rotatedRect.size.height - margin * 2;
//矩形起始坐标
roi.x = center.x - roi.width / 2;
roi.y = center.y - roi.height / 2; //目标框选超出范围部分像素直接砍掉
if (roi.x < 0) roi.x = 0;
if (roi.y < 0) roi.y = 0;
if (roi.x + roi.width > src.cols)
{
roi.width = src.cols - roi.x;
}
if (roi.y + roi.height > src.rows)
{
roi.height = src.rows - roi.y;
} cv::Mat dst(src.rows, src.cols, CV_8UC3, cv::Scalar(0, 0, 0));
//获取仿射矩阵 M
cv::Mat matrix2D = cv::getRotationMatrix2D(center, angle, 1);
//变换图像
cv::warpAffine(src, dst, matrix2D, cv::Size(src.cols, src.rows)); //ROI 最终结果
cv::Mat ret(dst,roi);
#if 0
cv::namedWindow("Return");
cv::imshow("Return",ret);
#endif
return ret;
}
cv::Mat MaxBoxSelectionRotatedRect(cv::Mat& src, cv::RotatedRect& ret)
{
cv::Mat dst = src.clone();
//颜色模型转换
cv::cvtColor(src, src, cv::COLOR_BGR2HSV_FULL);
//cv::Mat 向量容器
std::vector<cv::Mat> threeChannels;
//分割HSV模型,提取 V(亮度) 通道
cv::split(src, threeChannels);
cv::threshold(threeChannels.back(), src, 0, 255, cv::THRESH_OTSU);
std::vector<std::vector<cv::Point>> contours;
cv::findContours(src, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
//假设最大轮廓值向量容器索引
size_t maxContoursIndex = contours.size() - 1;
//遍历向量容器
for (size_t i = maxContoursIndex; i > 0; i--)
{
//寻找最大点集
//if (contours.at(i).size() > contours.at(maxContoursIndex).size())
//寻找最大的轮廓
if (cv::contourArea(contours.at(i)) > cv::contourArea(contours.at(maxContoursIndex)))
{
//最大轮廓在向量容器中的位置
maxContoursIndex = i;
}
} //std::cout << "contourAreaMax:" << cv::contourArea(contours.at(maxContoursIndex)) << std::endl;
if (cv::contourArea(contours.at(maxContoursIndex)) < 488.0)//double minAreaRectSize = 488;
{
return dst;
} ret = cv::minAreaRect(contours.at(maxContoursIndex)); const int pixel = 10;
const int defaultPixel = 5000000;
int lineWidth = 2 * (dst.cols * dst.rows / 5000000);
cv::Point2f pts[4];
ret.points(pts);
#if 1
//绘制最小外接矩形
for (int i = 0; i < 4; ++i) {
line(dst, pts[i], pts[(i + 1) % 4], cv::Scalar(0, 255, 0), lineWidth);
}
#else
roi = dst(cv::boundingRect(contours.at(maxContoursIndex)));
//绘制最大外接矩形
cv::rectangle(dst, cv::boundingRect(contours.at(maxContoursIndex)), cv::Scalar(0, 255, 0), 2, 8);
#endif
return dst;
}

Opencv 330 如何裁剪图片中大的目标?的更多相关文章

  1. Java+jquery实现裁剪图片上传到服务器

    大体分两步: 1.利用jquery裁剪图片,把裁剪到的几个点传入后端 2.利用前端传入的几个点,来裁剪图片 首先,用到一个jquery的插件 imgAreaSelect 实例及插件下载地址:http: ...

  2. PHP图片裁剪与缩放 / 无损裁剪图片

    图片太大且规格不统一,显示的控制需要靠JavaScript来完成,用在移动设备上时显示效果不好且流量巨大,需要对现有图片库的图片进行一次处理,生成符合移动设备用的缩略图,将原来客户端JS做的工作转移到 ...

  3. PHP裁剪图片

    PHP裁剪图片 $src_path = '1.jpg'; //创建源图的实例 $src = imagecreatefromstring(file_get_contents($src_path)); / ...

  4. 【转】java缩放图片、java裁剪图片代码工具类

    一首先看下效果 二工具类 三测试类 在系统的上传图片功能中,我们无法控制用户上传图片的大小,用户可能会上传大到几十M小到1k的的图片,一方面图片太大占据了太多的空间,另一方面,我们没办法在页面上显示统 ...

  5. MVC使用JCrop上传、裁剪图片

    JCrop用来裁剪图片,本篇想体验的是: 在视图页上传图片: 上传成功,跳转到另外一个编辑视图页,使用JCrop对该图片裁剪,并保存图片到指定文件夹: 裁剪成功后,在主视图页显示裁剪图片: 当然,实际 ...

  6. java裁剪图片

    java裁剪图片保存到指定位置 /** * 图片裁剪通用接口 * * @param src 源图片地址,图片格式PNG * @param dest 目的图片地址 * @param x 图片起始点x坐标 ...

  7. Flutter裁剪图片

    最近在学习中需要用到裁剪图片,记录一下解决方法 思路: 使用canvas的drawImageRect()方法,对Image进行裁剪,这里的Image需要 'dart:ui' 库中的Image. 1. ...

  8. iOS开发——UI进阶篇(十八)核心动画小例子,转盘(裁剪图片、自定义按钮、旋转)图片折叠、音量震动条、倒影、粒子效果

    一.转盘(裁剪图片.自定义按钮.旋转) 1.裁剪图片 将一张大图片裁剪为多张 // CGImageCreateWithImageInRect:用来裁剪图片 // image:需要裁剪的图片 // re ...

  9. IOS 按比例裁剪图片

    拍照或者从图片库中获取图片 操作过程中容易闪退,也总会有内存压力警告,第一步,首先可以考虑裁剪图片,实际上可能不需要那么大的.其次可以考虑把耗时的比如存储过程放进线程. 这里封装裁剪图片的类方法. / ...

随机推荐

  1. confirm显示数组中的内容时,总是带一个逗号分隔的解决方法

    问题的关键 就是在给confirm显示之前,将数组转换成字符串,并以每个数组的元素为一个字符串,加上一个换行回车符即可: 代码中的背景色 为关键的点 <script type="tex ...

  2. java—— finall 关键词

    _ *{ margin: 0; padding: 0; } .on2{ margin: 10px 0; cursor: pointer; user-select: none; color: white ...

  3. common-logging--源码之SimpleLog

    common-logging源码Log接口 在common-logging的源码中,将log核心类抽象成了一个Log接口. 这里贴出Log接口的源码: /* * Licensed to the Apa ...

  4. 【转】Matlab作图语句小结

    之前用Matlab作图,从网上找了些别人的例子,然后慢慢调参数.其实对很多命令,特别是对句柄不是很了解,今天简单总结了一下.下面用几个例子来说明:     ]);  首先,gcf是当前figure对象 ...

  5. 八大排序算法Java实现

    本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...

  6. 禁掉或启用firefox 的 javascript 脚本

    老版本的firefox可以直接在“选项”页设置启用或禁用javascript 脚本 新版的Firefox中,我找了半天,没有找到,看来是没法直接设置了 于是在 地址栏键入 about:config 搜 ...

  7. Spring的事务管理(理论篇,下篇提供代码实现)

    事务:逻辑上的一组操作,这组操作要么全部成功,要么全部失败(事务十大特性:原子性,一致性,隔离性,持久性) 原子性:事务是不可分割的工作单位,事务中的操作要么都发生了,要么都不发生.(也就是说不能单独 ...

  8. Linux 虚拟机忘记root密码

    Linux 虚拟机忘记root密码可以按照下面的步骤重新设置密码: 1.在grub界面,也就是有press any key的那个界面,按下任意键 2.键入e,出现三行文字,按上下键选择kernel那一 ...

  9. JMX与Spring

    1.什么是JMX JMX可以监控类的运行情况,可以在程序运行期查看并修改类属性的信息. 举一个应用实例:在一个系统中常常会有一些配置信息,比如服务的IP地址,端口号什么的,那么如何来写这些代码呢? 下 ...

  10. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...