gpt4 book ai didi

opencv - 使用opencv区分岩石场景

转载 作者:太空宇宙 更新时间:2023-11-03 21:03:16 25 4
gpt4 key购买 nike

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

enter image description here enter image description here

我想要实现的是找到轮廓周围的特征,例如:

  • 浅色区域
  • 暗区
  • 灰色区域
  • 灰色区域
  • 等直到灰色区域

(区域数量应作为选择的参数)

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

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

不幸的是,您可以很容易地看出,颜色并不能真正代表原始的大型图像特征!例如:查看我用红色圈出的两个区域——这些特征几乎完全被另一种颜色淹没了。我的想象是,至少非常亮和非常暗的区域被它自己的颜色覆盖。

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);

最佳答案

我认为您可以为此使用简单的聚类,例如 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')

结果:

enter image description here

关于opencv - 使用opencv区分岩石场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24683105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com