zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    IDEA远程仓库版本回滚
    智能风控平台核心之风控决策引擎(三)
    智能风控平台核心之风控决策引擎(一)
    深入理解Oracle的imp/exp 和各版本之间的规则
    oracle忘记用户密码
    Windows下使用cmd启动Oracle EM和sql命令使用+主机身份认证
    jsp调用javabean出现错误HTTP Status 500
    jsp查询页面和结果页面在同一页面显示和交互
    javabean+servlet+jsp程序_个人辛苦探索
    用Eclipse 开发Dynamic Web Project应用程序 【转】
  • 原文地址:https://www.cnblogs.com/cheungxiongwei/p/8303325.html
Copyright © 2011-2022 走看看