C++ Opencv——影象處理(預處理+矩形物體分割)
阿新 • • 發佈:2018-12-20
影象預處理分割目標
// 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; }