Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用opencv区分岩石场景_Opencv - Fatal编程技术网

使用opencv区分岩石场景

使用opencv区分岩石场景,opencv,Opencv,我正在努力寻找适合低质量图像的轮廓算法。示例图像显示了一个岩石场景: 我试图实现的是在特征周围找到轮廓,例如: 光区 暗区 灰色区域 灰色区域 等,直到灰色区域 (面积数量应为选择参数) 我不想采用简单的二进制阈值,而是使用某种轮廓查找(例如分水岭或其他)。主要特征线应保持不变,特征内的噪声可以被抑制 我的代码的结果可以在右边的图片上看到 不幸的是,正如你可以很容易地告诉,颜色并不真正代表原来的大规模图像功能!例如:查看我用红色圈出的两个区域-这些功能几乎完全被另一种颜色淹没。我想象的是

我正在努力寻找适合低质量图像的轮廓算法。示例图像显示了一个岩石场景:

我试图实现的是在特征周围找到轮廓,例如:

  • 光区
  • 暗区
  • 灰色区域
  • 灰色区域
  • 等,直到灰色区域
(面积数量应为选择参数)

我不想采用简单的二进制阈值,而是使用某种轮廓查找(例如分水岭或其他)。主要特征线应保持不变,特征内的噪声可以被抑制

我的代码的结果可以在右边的图片上看到

不幸的是,正如你可以很容易地告诉,颜色并不真正代表原来的大规模图像功能!例如:查看我用红色圈出的两个区域-这些功能几乎完全被另一种颜色淹没。我想象的是,至少很亮和很暗的区域都被它自己的颜色覆盖着

cv::Mat cv_src = cv::imread(argv[1]);
cv::Mat output;
cv::Mat cv_src_gray;

cv::cvtColor(cv_src, cv_src_gray, cv::COLOR_RGB2GRAY);

double clipLimit = 0.1;
cv::Size titleGridSize = cv::Size(8,8);
cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(clipLimit, titleGridSize);
clahe->apply(cv_src_gray, output);

cv::equalizeHist(output, output);

cv::cvtColor(output, cv_src, cv::COLOR_GRAY2RGB);
// Create binary image from source image
cv::Mat bw;
cv::cvtColor(cv_src, bw, cv::COLOR_BGR2GRAY);
cv::threshold(bw, bw, 180, 255, cv::THRESH_BINARY);

// Perform the distance transform algorithm
cv::Mat dist;
cv::distanceTransform(bw, dist, cv::DIST_L2, CV_32F);

// Normalize the distance image for range = {0.0, 1.0}
cv::normalize(dist, dist, 0, 1., cv::NORM_MINMAX);

// Threshold to obtain the peaks
cv::threshold(dist, dist, .2, 1., cv::THRESH_BINARY);

// Create the CV_8U version of the distance image
cv::Mat dist_8u;
dist.convertTo(dist_8u, CV_8U);

// Find total markers
std::vector<std::vector<cv::Point> > contours;
cv::findContours(dist_8u, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
int ncomp = contours.size();

// Create the marker image for the watershed algorithm
cv::Mat markers = cv::Mat::zeros(dist.size(), CV_32S);

// Draw the foreground markers
for (int i = 0; i < ncomp; i++)
    cv::drawContours(markers, contours, i, cv::Scalar::all(i+1), -1);

// Draw the background marker
cv::circle(markers, cv::Point(5,5), 3, CV_RGB(255,255,255), -1);

// Perform the watershed algorithm

cv::watershed(cv_src, markers);

// Generate random colors
std::vector<cv::Vec3b> colors;
for (int i = 0; i < ncomp; i++)
{
    int b = cv::theRNG().uniform(0, 255);
    int g = cv::theRNG().uniform(0, 255);
    int r = cv::theRNG().uniform(0, 255);

    colors.push_back(cv::Vec3b((uchar)b, (uchar)g, (uchar)r));
}

// Create the result image
cv::Mat dst = cv::Mat::zeros(markers.size(), CV_8UC3);

// Fill labeled objects with random colors
for (int i = 0; i < markers.rows; i++)
{
    for (int j = 0; j < markers.cols; j++)
    {
        int index = markers.at<int>(i,j);
        if (index > 0 && index <= ncomp)
            dst.at<cv::Vec3b>(i,j) = colors[index-1];
        else
            dst.at<cv::Vec3b>(i,j) = cv::Vec3b(0,0,0);
    }
}

// Show me what you got
imshow("final_result", dst);
cv::Mat cv_src=cv::imread(argv[1]);
cv::Mat输出;
cv::Mat cv_src_gray;
cv::cvtColor(cv_src,cv_src_gray,cv::COLOR_RGB2GRAY);
双clipLimit=0.1;
cv::Size titleGridSize=cv::Size(8,8);
cv::Ptr clahe=cv::createCLAHE(clipLimit,titleGridSize);
类别->应用(cv\U src\U灰色,输出);
cv::equalizeHist(输出,输出);
cv::cvtColor(输出,cv_src,cv::COLOR_GRAY2RGB);
//从源图像创建二进制图像
cv::Mat bw;
cv::CVT颜色(cv_src、bw、cv::颜色_bgr2灰色);
cv::threshold(bw,bw,180,255,cv::THRESH_二进制);
//执行距离变换算法
cv::Mat dist;
距离变换(bw,dist,cv::dist_L2,cv_32F);
//规范化范围={0.0,1.0}的距离图像
cv::normalize(dist,dist,0,1.,cv::NORM_MINMAX);
//获取峰值的阈值
cv::threshold(dist,dist,.2,1.,cv::THRESH_二进制);
//创建距离图像的CV_8U版本
cv::Mat dist_8u;
变换区(变换区8u、变换区8u);
//查找总标记
矢量轮廓;
cv::findContours(距离8u,轮廓,cv::RETR\u外部,cv::CHAIN\u近似\u简单);
int ncomp=等高线.size();
//为分水岭算法创建标记图像
cv::Mat markers=cv::Mat::Zero(距离大小(),cv_32S);
//绘制前景标记
对于(int i=0;i如果(index>0&&index我想你可以使用一个简单的聚类,比如k-means,然后检查聚类中心(或者每个聚类的平均值和标准偏差)。我很快在matlab中进行了尝试

im = imread('tvBqt.jpg');
gr = rgb2gray(im);

x = double(gr(:));
idx = kmeans(x, 4);
cl = reshape(idx, 600, 472);

figure,
subplot(1, 2, 1), imshow(gr, []), title('original')
subplot(1, 2, 2), imshow(label2rgb(cl), []), title('clustered')
结果是:


您可以尝试使用SLIC超级像素。我尝试了它,并显示了一些良好的结果。您可以改变参数以获得更好的聚类效果


在提取等高线之前,我会考虑使用Canny算法,我会考虑使用冲蚀和膨胀,或者考虑一些通滤波器,以增加照片的色度之间的对比度,非常感谢SLIC Sycel的想法。然而,由于我试图在相同颜色的区域中建立轮廓。(或在本例中为灰色级别),SLIC的想法在我看来并不正确……你这是什么意思?你尝试过改变参数吗?它可能会给出更好的结果。还有SLICO不需要任何参数。我想我不完全理解如何扣除(例如5)灰度级的颜色及其产生的闭合计数围绕着这样的超像素。我相信人们会找到合适的参数,以便沿着灰度级排列大像素。但同样,我最终需要一个灰度级周围的整个轮廓(而不是同一灰度级的多个大像素分割计数…)。