图像预处理分割目标
// ROI提取
Mat Image_ROI(Mat frame)
{
Mat gray, bw, img, bkup;
/*目标提取——预处理——Mat ROI*/
/*预处理很重要——直接找到目标*/
//预处理很重要——直接找到目标
// 灰度化
cv::cvtColor(frame, gray, CV_BGR2GRAY);
img = gray.clone();
// 高斯滤波
cv::GaussianBlur(img, img, Size(5, 5), 0, 0); //高斯滤波
// 膨胀操作
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); //第一个参数MORPH_RECT表示矩形的卷积核,当然还可以选择椭圆形的、交叉型的
cv::dilate(img, img, element); //实现过程中发现,适当的膨胀很重要
//边缘检测
cv::Canny(img, img, 30, 120, 3); //边缘提取
//namedWindow("get contour", 1);
// cv::imshow("get contour", img);
//从包好目标轮廓里面找矩形的轮廓
/**/
bkup = gray.clone();
Mat dstImg = frame.clone();
// cv::imshow("原图", dstImg);//原图
/**/
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
cv::findContours(img, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
vector<Rect> boundRect(contours.size());
vector<RotatedRect> box(contours.size());
Point2f rect[4];
Mat image_object;
for (int i = 0; i < contours.size(); i++)
{
box[i] = minAreaRect(Mat(contours[i]));
if (box[i].size.width < 100 || box[i].size.height < 100)//筛选
continue;
//rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
//circle(dstImg, Point(box[i].center.x, box[i].center.y), 5, Scalar(255, 255, 0), -1, 8);
box[i].points(rect);
/*for (int j = 0; j<4; j++)
{
line(dstImg, rect[j], rect[(j + 1) % 4], Scalar(255, 0, 255), 2, 8);
}*/
float angle;
std::cout << "angle=" << box[i].angle << endl;
angle = box[i].angle;
char width[20], height[20];
sprintf_s(width, "width=%0.2f", box[i].size.width);
sprintf_s(height, "height=%0.2f", box[i].size.height);
//putText(dstImg, width, Point(195, 260), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(255, 255, 0));
//putText(dstImg, height, Point(190, 285), CV_FONT_HERSHEY_COMPLEX_SMALL, 0.85, Scalar(255, 255, 0));
//利用仿射变换进行旋转 另一种方法,透视变换
if (0 < abs(angle) && abs(angle) <= 45)
angle = angle;//负数,顺时针旋转
else if (45 < abs(angle) && abs(angle) < 90)
angle = 90 - abs(angle);//正数,逆时针旋转
Point2f center = box[i].center; //定义旋转中心坐标
double angle0 = angle;
double scale = 1;
Mat roateM = getRotationMatrix2D(center, angle0, scale); //获得旋转矩阵,顺时针为负,逆时针为正
Mat roate_img;
warpAffine(dstImg, roate_img, roateM, dstImg.size()); //仿射变换结果frame
// imshow("roateM", roate_img);
/**/
boundRect[i] = boundingRect(Mat(contours[i]));
//显示昉射后的目标区域图
int x0 = 0, y0 = 0, w0 = 0, h0 = 0;
x0 = boundRect[i].x;
y0 = boundRect[i].y;
w0 = boundRect[i].width;
h0 = boundRect[i].height;
Mat ROI = roate_img(Rect(x0, y0, w0, h0));//截取对应的区域
//imshow("ROI", ROI);
image_object = ROI;
imwrite("测试ROI的准确性.jpg", ROI);
}
return image_object;
}