openCV小案例(一)-- 图像切边

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
旋转图形效果,旋转后按步骤一再处理一次即可
在这里插入图片描述

#include<opencv2/opencv.hpp>
#include<math.h>
#include<iostream>

using namespace cv;
using namespace std;

Mat src2;
Mat src,dst,gray_src,temp,dst1;
const char* output_win = "output_img";
RNG rng(12345);
int threshold_v = 100;
int threshold_max = 255;
void Demo_Moments(int, void*);
//当图片有旋转角度时的处理函数
void Check_Skew(int, void*);
int main(int argc, char** argv) {
	src = imread("C:/Users/18929/Desktop/博客项目/项目图片/12.jpg");
	if (src.empty()) {
		printf("could not load image");
		return -1;
	}
	imshow("input_img", src);


	src2 = imread("C:/Users/18929/Desktop/博客项目/项目图片/13.jpg");
	if (src2.empty()) {
		printf("could not load image");
		return -1;
	}
	imshow("input_img", src2);
	
	//namedWindow(output_win, WINDOW_AUTOSIZE);
	//createTrackbar("Threshold value is:", output_win, &threshold_v, threshold_max, Demo_Moments);
	//Demo_Moments(0, 0);
	Check_Skew(0, 0);

	waitKey(0);
	return 0;
}

void Check_Skew(int, void*) {
	//边缘提取
	cvtColor(src2, gray_src, COLOR_BGR2GRAY);
	Mat canny_out;
	Canny(gray_src, canny_out, threshold_v, threshold_v * 2, 3, false);
	imshow("canny_img", canny_out);

	//寻找轮廓并绘制
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(canny_out, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

	float maxw = 0;
	float maxh = 0;
	double degree = 0;
	RNG rng(12345);
	Mat drawImage = Mat::zeros(src2.size(), CV_8UC3);
	for (size_t i = 0; i < contours.size(); i++)
	{
		//找出最小的长方形轮廓
		RotatedRect minRect = minAreaRect(contours[i]);
		//因为角度可能是负,所以要加绝对值
		float degree = abs(minRect.angle);
		if (degree>0)
		{
			//如果有倾斜角度,找到最大的边框对象,然后进行旋转,转回正常角度
			maxw = max(maxw, minRect.size.width);
			maxh = max(maxh, minRect.size.height);
		}
	}
	//画出边框
	for (size_t t = 0; t < contours.size(); t++)
	{
		RotatedRect minRect = minAreaRect(contours[t]);
		//找到正确矩形时才华
		if (maxw == minRect.size.width && maxh == minRect.size.height)
		{
			degree = minRect.angle;
			Point2f pts[4];
			minRect.points(pts);
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			for (int j = 0; j < 4; j++)
			{
				line(drawImage, pts[j], pts[(j + 1) % 4], color, 2, 8, 0);
			}
		}
	}
	imshow("line", drawImage);

	//旋转图形
	//1.获取中心点
	Point2f center(src2.cols / 2, src.rows / 2);
	//2.以倾斜图形和旋转角度获取需要旋转的矩阵
	Mat rotm = getRotationMatrix2D(center, degree, 1.0);
	Mat dst;
	//3.使用仿射变换旋转图形
	warpAffine(src2, dst, rotm, src2.size(), INTER_LINEAR, 0, Scalar(255,255,255));
	imshow("normal_result", dst);
}

void Demo_Moments(int, void*) {
	//边缘提取
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	Mat canny_out;
	Canny(gray_src, canny_out, threshold_v, threshold_v * 3, 3, false);
	imshow("canny_img", canny_out);

	//寻找轮廓并绘制
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(canny_out, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

	//限制轮廓大小,如果太小的不绘制
	int minw = src.cols * 0.75;
	int minh = src.rows * 0.75;
	RNG rng(12345);
	//设置一个矩形对象,仅装轮廓内图形,然后显示
	Rect bbox;
	Mat drawImage = Mat::zeros(src.size(), CV_8UC3);

	for (size_t t = 0; t < contours.size(); t++) {
		//找出最小的长方形轮廓
		RotatedRect minRect = minAreaRect(contours[t]);
		//找出倾斜角度,有倾斜再处理
		float degree = abs(minRect.angle);
		printf("current angle is:%f", degree);
		//画轮廓
		if (minRect.size.width>minw&&minRect.size.height>minh &&minRect.size.width<(src.cols))
		{
			//找出矩形的四个点连线
			Point2f pts[4];
			minRect.points(pts);
			//存储矩形区域,以边框为界
			bbox = minRect.boundingRect();
			Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
			for (int i = 0; i < 4; i++)
			{
				line(drawImage, pts[i], pts[(i + 1) % 4], color, 2, 8, 0);
			}
		}
	}
	imshow("contours", drawImage);
	if (bbox.width>0&&bbox.height>0)
	{
		//获取了bbox的区域后,再src中截取出相应部分
		Mat roiImg = src(bbox);
		imshow("final result", roiImg);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值