Opencv 330 如何裁剪图片中大的目标?
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 如何裁剪图片中大的目标?的更多相关文章
- Java+jquery实现裁剪图片上传到服务器
大体分两步: 1.利用jquery裁剪图片,把裁剪到的几个点传入后端 2.利用前端传入的几个点,来裁剪图片 首先,用到一个jquery的插件 imgAreaSelect 实例及插件下载地址:http: ...
- PHP图片裁剪与缩放 / 无损裁剪图片
图片太大且规格不统一,显示的控制需要靠JavaScript来完成,用在移动设备上时显示效果不好且流量巨大,需要对现有图片库的图片进行一次处理,生成符合移动设备用的缩略图,将原来客户端JS做的工作转移到 ...
- PHP裁剪图片
PHP裁剪图片 $src_path = '1.jpg'; //创建源图的实例 $src = imagecreatefromstring(file_get_contents($src_path)); / ...
- 【转】java缩放图片、java裁剪图片代码工具类
一首先看下效果 二工具类 三测试类 在系统的上传图片功能中,我们无法控制用户上传图片的大小,用户可能会上传大到几十M小到1k的的图片,一方面图片太大占据了太多的空间,另一方面,我们没办法在页面上显示统 ...
- MVC使用JCrop上传、裁剪图片
JCrop用来裁剪图片,本篇想体验的是: 在视图页上传图片: 上传成功,跳转到另外一个编辑视图页,使用JCrop对该图片裁剪,并保存图片到指定文件夹: 裁剪成功后,在主视图页显示裁剪图片: 当然,实际 ...
- java裁剪图片
java裁剪图片保存到指定位置 /** * 图片裁剪通用接口 * * @param src 源图片地址,图片格式PNG * @param dest 目的图片地址 * @param x 图片起始点x坐标 ...
- Flutter裁剪图片
最近在学习中需要用到裁剪图片,记录一下解决方法 思路: 使用canvas的drawImageRect()方法,对Image进行裁剪,这里的Image需要 'dart:ui' 库中的Image. 1. ...
- iOS开发——UI进阶篇(十八)核心动画小例子,转盘(裁剪图片、自定义按钮、旋转)图片折叠、音量震动条、倒影、粒子效果
一.转盘(裁剪图片.自定义按钮.旋转) 1.裁剪图片 将一张大图片裁剪为多张 // CGImageCreateWithImageInRect:用来裁剪图片 // image:需要裁剪的图片 // re ...
- IOS 按比例裁剪图片
拍照或者从图片库中获取图片 操作过程中容易闪退,也总会有内存压力警告,第一步,首先可以考虑裁剪图片,实际上可能不需要那么大的.其次可以考虑把耗时的比如存储过程放进线程. 这里封装裁剪图片的类方法. / ...
随机推荐
- 摘-BMC自动化解决方案产品概览
以下内容摘自BMC解决方案白皮书 BMC 解决方案助力您的企业快速享受自动化带来的快速效益,并随时间推移实现这些优势的最大化. BMC 自动化技术可帮助您优化敏捷性,同时保持必要的治理和合规性控制.无 ...
- Servlet--HttpServletRequest接口,HttpServletResponse接口
HttpServletRequest接口 定义 public interface HttpServletRequest extends ServletRequest; 用来处理一个对 Servlet ...
- java IO 类库的基本架构
I/O问题是任何编程语言都无法回避的问题,可以说I/O问题是整个人机交互的核心问题,因为I/O是机器获取和交换信息的主要渠道,在当今这个数据大爆炸时代,I/O问题尤为突出,很容易成为一个性能瓶颈.正因 ...
- Android ui 透明度设置
格式如#00FFFFFF,前两位代表不透明度的十六进制.00表示完全透明,FF就是全不透明.依次递增. <?xml version="1.0" encoding=" ...
- docker入门(一)
1. Docker是什么? 官方的解释地址: Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署 ...
- 【转】sed命令n,N,d,D,p,P,h,H,g,G,x解析
1. sed执行模板=sed '模式{命令1;命令2}' 即逐行读入模式空间,执行命令,最后输出打印出来 2. 为方便下面,先说下p和P,p打印当前模式空间内容,追加到默认输出之后,P打印当前模式空间 ...
- redis数据类型-列表类型
列表类型 列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段. 列表类型内部是使用双向链表(double linked list)实现的,所以向 ...
- 常用的几个PHP加密函数
1.前言 PHP加密方式分为单项散列加密,对称加密,非对称加密这几类. 像常用的MD5.hash.crypt.sha1这种就是单项散列加密,单项散列加密是不可逆的. 像URL编码.base64编码这种 ...
- 【mac】mac os X更新High Sierra后出现的问题
今天更新了一下macbook pro的系统到10.13.1版本,出现了几个小问题,总结一下解决方案: git客户端无法使用 解决方案如下: http://blog.csdn.net/kedongjun ...
- Effective Java 之-----精确的答案与double&float
题目: 假设你口袋里有1$,看到货架上有一排美味的糖果,标价分别为0.10$,0.20$,0.30$...1$,你打算从标价为0.10$的糖果开始买起,每种买一颗,一直到不能支付货架上下一种价格的糖果 ...