C# 是否有可能找到“a”的边缘;“斑点”;emgucv的地区?
我有一张像这样的图片: 我想找到像这样的黑暗部分的边缘(红线就是我要找的): 我已经尝试了一些方法,但都没有成功,所以我希望有一位埃古古大师愿意帮助我 方法1C# 是否有可能找到“a”的边缘;“斑点”;emgucv的地区?,c#,.net,opencv,image-processing,emgucv,C#,.net,Opencv,Image Processing,Emgucv,我有一张像这样的图片: 我想找到像这样的黑暗部分的边缘(红线就是我要找的): 我已经尝试了一些方法,但都没有成功,所以我希望有一位埃古古大师愿意帮助我 方法1 将图像转换为灰度 消除噪音并反转 去掉任何不太亮的东西 获取canny和多边形 这方面的代码(我知道我应该正确处理事情,但我保持代码简短): var orig=新图像(内嵌); var等值线=原始值 .Convert() 派尔当先生() 皮鲁普先生() .不是() .InRange(新灰色(190)、新灰色(255)) .坎尼(新
- 将图像转换为灰度
- 消除噪音并反转
- 去掉任何不太亮的东西
- 获取canny和多边形
var orig=新图像(内嵌);
var等值线=原始值
.Convert()
派尔当先生()
皮鲁普先生()
.不是()
.InRange(新灰色(190)、新灰色(255))
.坎尼(新格雷(190)、新格雷(255))
.FindContours(链近似法。CV链近似法),
再生类型:CV(再生树);
var输出=新图像(原始大小);
对于(;轮廓!=null;轮廓=轮廓.HNext)
{
var poly=等高线近似多边形(等高线周长*0.05,
(a)储存);
输出.绘制(多边形,新灰色(255),1);
}
输出保存(输出文件);
结果是:
方法2
- 将图像转换为灰度
- 消除噪音并反转
- 去掉任何不太亮的东西
- 拿着机灵的,然后排队
var orig = new Image<Bgr, byte>(inFile);
var linesegs = orig
.Convert<Gray, byte>()
.PyrDown()
.PyrUp()
.Not()
.InRange(new Gray(190), new Gray(255))
.Canny(new Gray(190), new Gray(255))
.HoughLinesBinary(
1,
Math.PI/45.0,
20,
30,
10
)[0];
var output = new Image<Gray, byte>(orig.Size);
foreach (var l in linesegs)
{
output.Draw(l, new Gray(255), 1);
}
output.Save(outFile);
var orig=新图像(内嵌);
变量linesegs=orig
.Convert()
派尔当先生()
皮鲁普先生()
.不是()
.InRange(新灰色(190)、新灰色(255))
.坎尼(新格雷(190)、新格雷(255))
HoughLinesBinary先生(
1.
Math.PI/45.0,
20,
30,
10
)[0];
var输出=新图像(原始大小);
foreach(linesegs中的变量l)
{
输出.绘图(l,新灰色(255),1);
}
输出保存(输出文件);
结果是:
注释
我尝试过调整这两种方法的所有参数并添加平滑,但我永远无法获得所需的简单边缘,因为我认为较暗的区域不是纯色
我也尝试过膨胀和腐蚀,但我必须为这些设置的参数太高,无法获得单一颜色,以至于我最终包括了右侧的一些灰色内容,并失去了准确性。是的,这是可能的,下面是您可以做到的方法:
- 更改图像的对比度以使较亮的部分消失:
- 然后,将其转换为HSV,在饱和信道上执行阈值操作:
- 并执行腐蚀和扩张操作以消除噪音:
这是我提出的C++代码,我相信你有能力把它转换成C::
#包括
#包括
int main(int argc,char*argv[])
{
cv::Mat image=cv::imread(argv[1]);
cv::Mat new_image=cv::Mat::zeros(image.size(),image.type());
/*改变对比度:新的_图像(i,j)=α*图像(i,j)+β*/
双α=1.8;//[1.0-3.0]
int beta=100;//[0-100]
对于(int y=0;y
此图像是否总是这样?可以将其转换为一维图像。这样可以消除一些噪音。如果你需要在2D尝试代码> CVAdvestItValue/Cord>中使用正确的参数,你应该能够调出噪音。谢谢,但它并不总是这样的——有时它会在中间很黑(所以不那么斑点),有时也不那么黑(虽然我给你展示了一个接近最坏的例子)。我尝试了自适应阈值,但最多我得到了一个图像,其中包含了许多白色点的中间部分,当转换为Canny得到的轮廓,你看到的方法1。我
var orig = new Image<Bgr, byte>(inFile);
var linesegs = orig
.Convert<Gray, byte>()
.PyrDown()
.PyrUp()
.Not()
.InRange(new Gray(190), new Gray(255))
.Canny(new Gray(190), new Gray(255))
.HoughLinesBinary(
1,
Math.PI/45.0,
20,
30,
10
)[0];
var output = new Image<Gray, byte>(orig.Size);
foreach (var l in linesegs)
{
output.Draw(l, new Gray(255), 1);
}
output.Save(outFile);
#include <cv.h>
#include <highgui.h>
int main(int argc, char* argv[])
{
cv::Mat image = cv::imread(argv[1]);
cv::Mat new_image = cv::Mat::zeros(image.size(), image.type());
/* Change contrast: new_image(i,j) = alpha*image(i,j) + beta */
double alpha = 1.8; // [1.0-3.0]
int beta = 100; // [0-100]
for (int y = 0; y < image.rows; y++)
{
for (int x = 0; x < image.cols; x++)
{
for (int c = 0; c < 3; c++)
{
new_image.at<cv::Vec3b>(y,x)[c] =
cv::saturate_cast<uchar>(alpha * (image.at<cv::Vec3b>(y,x)[c]) + beta);
}
}
}
cv::imshow("contrast", new_image);
/* Convert RGB Mat into HSV color space */
cv::Mat hsv;
cv::cvtColor(new_image, hsv, CV_BGR2HSV);
std::vector<cv::Mat> v;
cv::split(hsv,v);
// Perform threshold on the S channel of hSv
int thres = 15;
cv::threshold(v[1], v[1], thres, 255, cv::THRESH_BINARY_INV);
cv::imshow("saturation", v[1]);
/* Erode & Dilate */
int erosion_size = 6;
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS,
cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
cv::Point(erosion_size, erosion_size) );
cv::erode(v[1], v[1], element);
cv::dilate(v[1], v[1], element);
cv::imshow("binary", v[1]);
/* Bounding box */
// Invert colors
cv::bitwise_not(v[1], v[1]);
// Store the set of points in the image before assembling the bounding box
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = v[1].begin<uchar>();
cv::Mat_<uchar>::iterator end = v[1].end<uchar>();
for (; it != end; ++it)
{
if (*it) points.push_back(it.pos());
}
// Compute minimal bounding box
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
// Draw bounding box in the original image (debug purposes)
cv::Point2f vertices[4];
box.points(vertices);
for (int i = 0; i < 4; ++i)
{
cv::line(image, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 2, CV_AA);
}
cv::imshow("box", image);
cvWaitKey(0);
return 0;
}