使用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)灰度级的颜色及其产生的闭合计数围绕着这样的超像素。我相信人们会找到合适的参数,以便沿着灰度级排列大像素。但同样,我最终需要一个灰度级周围的整个轮廓(而不是同一灰度级的多个大像素分割计数…)。