C++ opencv入门学习2

裁剪图像
resize图像 裁切图像需要定义裁切的大小,用到了模板类Rect,可以在定义中找到构造函数,一般情况下Point指的的是左上角的点,Size是(width, height),分别为宽和高

void crop_img(string& path) {
Mat img = imread(path);
Mat imgcrop, resize_img;
Rect roi(Point(100, 100), Size(200, 300));
resize(img, resize_img, Size(), 0.5, 0.5, INTER_NEAREST);
imgcrop = img(roi);
imshow(“1”, img);
imshow(“1.5”, resize_img);
imshow(“2”, imgcrop);
waitKey();
destroyAllWindows();
}
轮廓检测
进行轮廓检测前,通常需要一些预处理操作,灰度处理或者阈值处理,进行高斯模糊(GaussianBlur),使用canny算子计算轮廓,之后利用用膨胀或者腐蚀操作使得轮廓尽可能是闭合的。

void preprocessing_(string &path) {

Mat img = imread(path);
Mat img_gray, img_Blur, img_Canny, img_Dil;

cvtColor(img, img_gray, COLOR_BGR2GRAY);
GaussianBlur(img_gray, img_Blur, Size(3, 3), 3, 0);
Canny(img_Blur, img_Canny, 25, 75);

Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); //膨胀的核大小
dilate(img_Canny, img_Dil, kernel);
//imshow("1", img_Dil);
getContours(img_Dil, img);
//画出轮廓

}
需要注意轮廓数据得保存格式vector>,可能会用到的一些函数arcLength可以计算轮廓得周长,contourArea计算轮廓的面积,通过这两个函数可以过滤掉一些不必要得噪声轮廓。approxPolyDP函数用于返回一个近似得多边形 画矩形框用rectangle(tl:top left, br:bottom right) 画轮廓用drawContours

void rectangle(InputOutputArray img, Point pt1, Point pt2,
const Scalar& color)
void drawContours( InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color)
void getContours(Mat imgDil, Mat img) {

vector<vector<Point>> contours;      //数据存储样例 {
   
   {(1,1),(1,2),(1,3)},{(),(),()},{(),(),(),()}}
vector<Vec4i> hierarchy;

findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//drawContours(img, contours, -1, Scalar(255, 0, 255), 2);

vector<vector<Point>> conPoly(contours.size());
vector<Rect> boundRect(contours.size());

for (int i = 0; i < contours.size(); i++)
{
    int area = contourArea(contours[i]);
    cout << "-------------------" << endl;
    cout << area << endl;
    string objectType;

    if (area > 1000)
    {
        float peri = arcLength(contours[i], true);   //perimeter(周长/边缘)
        approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);   //用更少的曲线来精确轮廓,所以输入和输出的数据类型应该是一致的,估计最小的角点
        cout << conPoly[i].size() << endl;

        boundRect[i] = boundingRect(conPoly[i]);  //返回包含轮廓点的最小矩形框, 

        int objCor = (int)conPoly[i].size();

        if (objCor == 3) { objectType = "Tri"; }
        else if (objCor == 4)
        {
            float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height;
            cout << aspRatio << endl;
            if (aspRatio > 0.95 && aspRatio < 1.05) { objectType = "Square"; }
            else { objectType = "Rect"; }
        }
        else if (objCor > 4) { objectType = "Circle"; }

        drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
        rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 5);     //画矩形框用rectangle(tl:top left, br:bottom right),画轮廓用drawContours
        //putText(img, objectType, { boundRect[i].x,boundRect[i].y }, FONT_HERSHEY_PLAIN, 1, Scalar(0, 69, 255), 2);
        putText(img, objectType, Point(boundRect[i].x, boundRect[i].y), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255), 1);
    }
}
imshow("img", img);
waitKey();
destroyAllWindows();

}
人脸检测
用opencv实现很简单得人脸检测

void face_detection(string &path) {
Mat img = imread(path);
CascadeClassifier face_detec; //定义一个层叠的分类器(多尺度)
face_detec.load(“F:/WTY/桌面/opencv/resources/haarcascade_frontalface_default.xml”);
if (face_detec.empty()) {
cout << “open failed” << endl;
}
vector faces;
int minNeighbors = 3; //目标至少被检测出几次才算真的检测出来
face_detec.detectMultiScale(img, faces, 1.1, minNeighbors);
for (int i = 0; i < faces.size(); i++) {
rectangle(img, faces.at(i), Scalar(0, 0, 255));
}
imshow(“face”, img);
waitKey();
destroyAllWindows();

}

猜你喜欢

转载自blog.csdn.net/qq_33867131/article/details/129117961