邻域算子和线性滤波函数

思路:

因为图像近于水平,所以采用sobel或者canny效果好一些;
车辙--sobel--滤波(不高斯)--
载入灰度图,先滤波,然后x,y方向梯度计算,分别水平/垂直阈值分割二值化,然后加权和

附上代码:

#include  
#include   
#include  
#include

using namespace cv;
using namespace std;

int main()
{
    //载入原始图    
    Mat image_gray_row = imread("kuang1.jpg", CV_LOAD_IMAGE_GRAYSCALE);  //工程目录下应该有一张名为1.jpg的素材图  
    Mat img_gray = image_gray_row.clone();

    resize(image_gray_row, img_gray, Size(image_gray_row.cols / 6, image_gray_row.rows / 6),0,0,INTER_LINEAR);
    imshow("【原图】", img_gray);

    blur(img_gray, img_gray, Size(3, 3));
    imshow("滤波", img_gray);
    imwrite("滤波.jpg",img_gray);

    Mat img_sobelX;
    Mat abs_img_sobelX;
    Sobel(img_gray, img_sobelX,CV_16S,1,0,3,1,1, BORDER_DEFAULT);
    convertScaleAbs(img_sobelX, abs_img_sobelX);
    imshow("【效果图】 X方向Sobel", abs_img_sobelX);
    imwrite("【效果图】 X方向Sobel.jpg",abs_img_sobelX);

    Mat img_sobelY;
    Mat abs_img_sobelY;
    Sobel(img_gray, img_sobelY, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
    convertScaleAbs(img_sobelY, abs_img_sobelY);
    imshow("【效果图】 Y方向Sobel", abs_img_sobelY);
    imwrite("【效果图】 Y方向Sobel.jpg", abs_img_sobelY);

    Mat dst;
    addWeighted(abs_img_sobelX, 0.5, abs_img_sobelY, 0.5, 0, dst);
    imshow("【效果图】整体方向Sobel", dst);
    imwrite("【效果图】整体方向Sobel.jpg",dst);

    Mat dst_up;
    Mat dst_upX;
    Mat dst_upY;
    dst_up.create(dst.size(), dst.type());
    dst_upX.create(dst.size(), dst.type());
    dst_upY.create(dst.size(), dst.type());

//    threshold(abs_img_sobelY, dst_upY, 96, 255, THRESH_OTSU + THRESH_BINARY);
//    imshow("检测垂直阈值分割", dst_upY);

//    threshold(img_sobelX, dst_upX, 96, 255, THRESH_OTSU + THRESH_BINARY);
//    imshow("检测水平阈值分割", dst_upX);

    threshold(dst, dst_up, 84, 255, THRESH_BINARY);
    imshow("整体二值化",dst_up);
    imwrite("整体二值化.jpg", dst_up);


    waitKey(0);
    return 0;
}

提示:注意全局变量!!!! Mat 和 参数都得是全局变量!main里面不要重申!
附上带trackbar的代码:


#include 
#include 
#include  
#include   
#include  
#include  



using namespace cv;
using namespace std;

int threshold_value = 30;

Mat image_gray_row, img_gray, img_sobelX, abs_img_sobelX, img_sobelY, abs_img_sobelY, dst, dst_up, dst_upX, dst_upY;

/// 自定义函数声明
static void Threshold_Demo(int, void*);


int main()
{
    //载入原始图    
    image_gray_row = imread("kuang1.jpg", CV_LOAD_IMAGE_GRAYSCALE);  
    img_gray = image_gray_row.clone();

    resize(image_gray_row, img_gray, Size(image_gray_row.cols / 6, image_gray_row.rows / 6), 0, 0, INTER_LINEAR);


    blur(img_gray, img_gray, Size(3, 3));





    Sobel(img_gray, img_sobelX, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
    convertScaleAbs(img_sobelX, abs_img_sobelX);




    Sobel(img_gray, img_sobelY, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
    convertScaleAbs(img_sobelY, abs_img_sobelY);


    addWeighted(abs_img_sobelX, 0.5, abs_img_sobelY, 0.5, 0, dst);



    dst_up.create(dst.size(), dst.type());
    dst_upX.create(dst.size(), dst.type());
    dst_upY.create(dst.size(), dst.type());

    //    threshold(abs_img_sobelY, dst_upY, 96, 255, THRESH_OTSU + THRESH_BINARY);
    //    imshow("检测垂直阈值分割", dst_upY);

    //    threshold(img_sobelX, dst_upX, 96, 255, THRESH_OTSU + THRESH_BINARY);
    //    imshow("检测水平阈值分割", dst_upX);



    namedWindow("Demo", CV_WINDOW_AUTOSIZE);
    //创建滑动条来控制阈值
    createTrackbar("Threshold",
        "Demo", &threshold_value,
        255, Threshold_Demo);

    Threshold_Demo(0, 0);//结果在回调函数中显示


    waitKey(0);
    return 0;
}

void Threshold_Demo(int, void*)
{

    threshold(dst, dst_up, threshold_value, 255, THRESH_BINARY);

    imshow("Demo", dst_up);
}

待改进:


霍夫变换–找线
路–k只有一个,路正交—-拉普拉斯强化边缘,二值化

管道(拉普拉斯锐化/膨胀和腐蚀,二值化,分离,零交叉)

–以下为闭环区域

颜色特征识别(煤堆)—闭环后中间杂质()可忽略,已闭环
RGB,UIV,LAD,色态聚类(不固定集群,需要贪婪,簇的合并问题-中心点相近放一块-!-!-同一簇的分离(根据像素的距离再聚类),sobel算子迭代,识别出边缘轮廓后拼接填洞

膨胀和腐蚀

检测纹理复杂程度–判断煤堆

路灯(路灯两侧相对比较高–波峰波谷)