您现在的位置是:首页 > 文章详情

opencv提取保存轮廓图

日期:2018-10-15点击:700

pragma once

include "open2_public.h"

class ld_yjt_sub_image
{
public:

//获取src_mat的轮廓个数,介于nMinSzie和nMaxSize之间的才会放入到evc_contours中 bool getContours(const Mat& src_mat, vector<vector<Point>>& evc_contours, const int& nMinSzie = 500, const int& nMaxSize = 100000); //生成影像名称 string getNewImage(); //提取出子影像文件 bool extract_sub_image(const string& src_image, vector<string>& vec_sub_image);

private:

//错误信息 CString m_strErrMsg;

public:

ld_yjt_sub_image(); virtual ~ld_yjt_sub_image();

};

include "stdafx.h"

include "ld_yjt_sub_image.h"

int g_lImageCount = 0;

ld_yjt_sub_image::ld_yjt_sub_image()
{
}

ld_yjt_sub_image::~ld_yjt_sub_image()
{
}

//获取src_mat的轮廓个数,介于nMinSzie和nMaxSize之间的才会放入到evc_contours中
bool ld_yjt_sub_image::getContours(const Mat& src_mat, vector>& evc_contours,

const int& nMinSzie, const int& nMaxSize)

{

if (src_mat.empty()) { m_strErrMsg = "原始矩阵为空,无法获取轮廓个数"; return false; } if (src_mat.channels() != 3) { m_strErrMsg.Format("原始矩阵通道个数不为3个"); return false; } Mat mat_clone = src_mat.clone(); //灰度图像 cvtColor(mat_clone, mat_clone, COLOR_BGR2GRAY); //对图像进行二值化 threshold(mat_clone, mat_clone, 80, 255, THRESH_BINARY); vector<vector<Point>> evc_temp_contours; //提取轮廓元素 findContours(mat_clone, evc_temp_contours, CV_RETR_TREE, CHAIN_APPROX_NONE); for (int i = 0; i < evc_temp_contours.size(); i++) { if (evc_temp_contours[i].size() < nMinSzie || evc_temp_contours[i].size() > nMaxSize) //轮廓尺寸过小或者过大 continue; //添加进入容器 evc_contours.push_back(evc_temp_contours[i]); } return true;

}

//生成影像名称
string ld_yjt_sub_image::getNewImage()
{

string str_new_image = "new_image"; str_new_image.append(to_string(g_lImageCount++)); str_new_image.append(".jpg"); return str_new_image;

}

//提取出子影像文件
bool ld_yjt_sub_image::extract_sub_image(const string& src_image, vector& vec_sub_image)
{

Mat src_mat = imread(src_image); if (src_mat.empty()) { m_strErrMsg.Format("打开影像文件[%s]失败", src_image.c_str()); return false; } 
vector<vector<Point>> evc_contours; if (!getContours(src_mat, evc_contours)) return false; 
for (int i = 0; i < evc_contours.size(); i++) { //获取区域坐标 Rect rt = boundingRect(evc_contours[i]); //获取倾斜角度 RotatedRect rotate = minAreaRect(evc_contours[i]); //如果角度超过5度,就需要做旋转 float angle = rotate.angle; if (abs(angle) > 5) { cout << "倾斜角度大于5度" << endl; //获取矩形的四个坐标点 Point2f rectpoint[4]; rotate.points(rectpoint); //计算两条边的长度 int line1 = sqrt((rectpoint[1].y - rectpoint[0].y)*(rectpoint[1].y - rectpoint[0].y) + (rectpoint[1].x - rectpoint[0].x)*(rectpoint[1].x - rectpoint[0].x)); int line2 = sqrt((rectpoint[3].y - rectpoint[0].y)*(rectpoint[3].y - rectpoint[0].y) + (rectpoint[3].x - rectpoint[0].x)*(rectpoint[3].x - rectpoint[0].x)); //为了让正方形横着放,所以旋转角度是不一样的 if (line1 > line2) // angle = 90 + angle; //直接克隆一个矩阵 Mat warp_mat = src_mat(rt).clone(); //计算绕图像中点顺时针旋转50度缩放因子为0.8的旋转矩阵 Point center = Point(warp_mat.cols / 2, warp_mat.rows / 2); double scale = 1; //通过上面的旋转细节信息求得旋转矩阵 Mat rot_mat = getRotationMatrix2D(center, angle, scale); //旋转已扭曲图像 warpAffine(warp_mat, warp_mat, rot_mat, warp_mat.size()); //imshow("warp_mat", warp_mat); //再次提取轮廓 vector<vector<Point>> evc_warp_contours; if (!getContours(warp_mat, evc_warp_contours)) return false; 
 for (int j = 0; j<evc_warp_contours.size(); j++) { //获取区域坐标 Rect warp_rt = boundingRect(evc_warp_contours[j]); string ImageName = getNewImage(); imwrite(ImageName, warp_mat(warp_rt)); vec_sub_image.push_back(ImageName); } waitKey(0); } else { cout << "倾斜角度小于5度" << endl; /// 设置目标图像的大小和类型与源图像一致 Mat warp_dst = Mat::zeros(src_mat.rows, src_mat.cols, src_mat.type()); warp_dst.setTo(cv::Scalar(100, 0, 0)); src_mat(rt).copyTo(warp_dst); string str_new_image = getNewImage(); imwrite(str_new_image, warp_dst); vec_sub_image.push_back(str_new_image); } }

}

原文链接:https://yq.aliyun.com/articles/653396
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章