SRM Vision 暑期培训

by Leozheng @ SRMVision

§11 OpenCV图像处理实践

#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main() {
    auto img = imread("test.png", 0);
    Mat binary;
    threshold(img, binary, 140, 255, THRESH_BINARY);
    vector<vector<Point>> contours; // 轮廓
    vector<Vec4i> hierarchy; // 轮廓之间的层次关系
    findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_A
    PPROX_SIMPLE); // 提取轮廓
    for (int i = 0; i < contours.size(); ++i) {
        auto rect = boundingRect(contours[i]); // 返回Rect类型对象
        auto rotatedRect = minAreaRect(contours[i]); // 返回RotatedRect类型对象
        auto area = contourArea(contours[i]); // 轮廓的面积
        if (area < 100)
            continue;
        else
        // 描绘轮廓,需传入轮廓列表和轮廓的索引,画线的RGB颜色 (Scalar类型),和绘制线条的粗细
            drawContours(img, contours, i, Scalar(0, 0, 255), 2);
    }
    imshow("img", img); waitKey(0);
    return 0;
}

7.1.2 颜色提取

#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
    auto img = imread("test.png");
    Mat img_hsv, blue_mask, blue_res; 
    cvtColor(img, img_hsv, COLOR_BGR2HSV); // 转换为HSV
    
    // 在 HSV 空间中定义蓝色取值范围
    Scalar lower_blue(110, 100, 100), upper_blue(130, 255, 255);
    inRange(img_hsv, lower_blue, upper_blue, blue_mask);
    bitwise_and(img, img, blue_res, blue_mask);
    imshow("blue_res", blue_res);
    waitKey(0);
    return 0;
}

7.2 旋转与仿射变换

#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
    auto img = imread("test.png");
    // rows 为 x 方向长度, cols 为 y 方向长度
    auto M = getRotationMatrix2D(Point2f(img.rows / 2, img.cols / 2),90, 0.4);
    
    vector<Point2f> pts1{ Point2f(50,50),Point2f(200,50),Point2f(50,200) },
    pts2{ Point2f(10,100),Point2f(200,50),Point2f(100,250) };
    auto M = getAffineTransform(pts1, pts2);
    
    Mat dst;
    warpAffine(img, dst, M, Size(img.cols, img.rows));
    
    imshow("dst", dst);
    waitKey(0);
    return 0;
}

7.3 霍夫变换

#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main() {
    auto img = imread("test.png");
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    vector<Vec3f> circles;
    HoughCircles(gray, circles, HOUGH_GRADIENT, 1, 100, 100, 30, 5, 300);
    cout << "检测到圆的个数:" << circles.size();
    for (auto& cir : circles) // 圆心横坐标、纵坐标和圆半径
        circle(img, Point(cir[0], cir[1]), cir[2], Scalar(255, 255, 255), 2);
    imshow("img", img); waitKey(0);
    return 0;
}

7.4 拖动条demo

#include <opencv2/opencv.hpp>
using namespace cv;
void onChangeTrackBar(int pos, void* data) {
    Mat srcImage = *(Mat*)(data); // 强制类型转换
    Mat dstImage;
    // 根据滑动条的值对图像进行二值化处理
    threshold(srcImage, dstImage, pos, 255, THRESH_BINARY);
    imshow("debug", dstImage);
}
int main() {
    auto img = imread("test.png", 0);
    namedWindow("debug"); // 一定要先创建窗口,否则滑动条窗口不会显示
    imshow("debug", img);
    createTrackbar("binary_threshold", "debug", 0, 255, onChangeTrackBar, &img);
    waitKey(0);
    return 0;
}

第十一讲 - 作业:

自行寻找一张五线谱,先提取每行五线谱的轮廓,再对原图进行直线检测,在原图上画出五线谱的五根线。

 

进阶(选做):使用霍夫圆或自学斑点检测相关知识,检测音符。(提示:可以使用腐蚀膨胀等运算优化效果)

 

提交代码与运行截图。开学前提交即可。

感 谢

@ SRMVision