【OpenCV】音符提取(形态学实例)

提取水平线和垂直线


下图很好地诠释了腐蚀膨胀的操作原理。


自适应阈值

adaptiveThreshold()
void cv::adaptiveThreshold  (   InputArray  src,   OutputArray  dst,
                                double maxValue,   int adaptiveMethod,
                                int thresholdType, int  blockSize,  
                                double  C 
)   

说明:src为输入图像,dst为输出图像,maxValue是最大灰度值,
     adaptiveMethod有ADAPTIVE_THRESH_MEAN_C 、ADAPTIVE_THRESH_GAUSSIAN_C 
     blockSize为掩模大小,C为从均值或加权平均值中减去的常数值。


掩模

getStructuringElement()
Mat cv::getStructuringElement   (   int     shape,
                                    Size    ksize,
                                    Point   anchor = Point(-1,-1) 
)   

说明:shape有MORPH_RECT、MORPH_CROSS、MORPH_ELLIPSE。ksize为掩模大小。
     anchor为掩模中心,Point(-1,-1)默认中心。

代码示例

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int, char** argv)
{
    Mat src,bw,horizontal, vertical;

    char* filename = "../data/src.png";
    src = imread(filename, IMREAD_GRAYSCALE);
    if (src.empty()) { return -1; }
    imshow("src",src);

    adaptiveThreshold(~src, bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);    // 自适应阈值

    horizontal = bw.clone();
    vertical = bw.clone();

    Mat structure_h = getStructuringElement(MORPH_RECT, Size(horizontal.cols / 30, 1));
    Mat structure_v = getStructuringElement(MORPH_RECT, Size(1, vertical.rows / 30));

    erode(horizontal, horizontal, structure_h, Point(-1, -1));              // Point(-1,-1)默认中心
    dilate(horizontal, horizontal, structure_h, Point(-1, -1));

    erode(vertical, vertical, structure_v, Point(-1, -1));                  // Point(-1,-1)默认中心
    dilate(vertical, vertical, structure_v, Point(-1, -1));

    imshow("horizontal", horizontal);                                       // 水平
    imshow("vertical", vertical);                                           // 垂直

    bitwise_not(vertical, vertical);                                        // 取反

    Mat edges;
    adaptiveThreshold(vertical, edges, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, -2);

    Mat kernel = Mat::ones(2, 2, CV_8UC1);
    dilate(edges, edges, kernel);

    Mat smooth;
    vertical.copyTo(smooth);

    blur(smooth, smooth, Size(2, 2));                                       // 平滑

    smooth.copyTo(vertical, edges);                                         // vertical为输出,edges为同大小的掩模,
                                                                            // 掩模非零部分才被复制
    imshow("final", vertical);

    waitKey(0);

    return 0;
}


运行结果






版权声明:本文为u013165921原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。