我试图在图像中检测到一个巨大的亮斑。我这样做的方式是,我首先将其转换为COLOR_BGR2HLS_FULL
,采用绿色通道并将GuassianBlur应用于此,然后我使用THRESH_OTSU
获得阈值图像然后绘制轮廓:
self.result = cv2.cvtColor(self.result_array_color, cv2.COLOR_BGR2HLS_FULL)
self.result = self.result[:,:,1]
self.result = cv2.GaussianBlur(self.result,(25,25), 0)
以下是获得的图片的样子:
以下是所需图片的样子:
另外,我这样做的方式与所有相似类型的图像不一致。你有什么更好的建议吗?
谢谢!
答案 0 :(得分:1)
好吧,我得到了这个结果:
初始图像(我没有原始图像,所以我从你的绿线中删除了绿线):
使用GREEN频道进行处理:
然后使用带有方形窗口半径为32的Dilate和Erode过滤器来移除容器:
照明抑制滤镜(或高通滤镜 - 按图像的高斯平滑除法)使图像更加清晰:
最后一个门槛
您也可以平滑最终的面具
再次使用阈值以获得更平滑的结果:
答案 1 :(得分:1)
不,我还没有使用任何其他修复技术去除血管。 膨胀是某个区域内的最大值,Erode是最小值。我使用Dilate和Erode半径32和HighPass半径128。
代码在C#中:
public byte[] Dilate(byte[] image, int width, int height, int radius)
{
byte[] temp = new byte[image.Length];
byte[] result = new byte[image.Length];
//Dilate by X
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
byte v = 0;
for (int i = x - radius; i <= x + radius; i++)
if (i >= 0 && i < width)
v = Math.Max(v, image[i + y * width]);
temp[x + y * width] = v;
}
//Dilate by Y
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
byte v = 0;
for (int i = y - radius; i <= y + radius; y++)
if (i >= 0 && i < height)
v = Math.Max(v, temp[x + i * width]);
result[x + y * width] = v;
}
return result;
}
public byte[] Erode(byte[] image, int width, int height, int radius)
{
byte[] temp = new byte[image.Length];
byte[] result = new byte[image.Length];
//Dilate by X
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
byte v = 255;
for (int i = x - radius; i <= x + radius; i++)
if (i >= 0 && i < width)
v = Math.Min(v, image[i + y * width]);
temp[x + y * width] = v;
}
//Dilate by Y
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
byte v = 255;
for (int i = y - radius; i <= y + radius; y++)
if (i >= 0 && i < height)
v = Math.Min(v, temp[x + i * width]);
result[x + y * width] = v;
}
return result;
}
public byte[] HighPass(byte[] image, int width, int height, float radius)
{
byte[] smooth = GaussSmooth(image, width, height, (byte)radius);
byte[] result = new byte[image.Length];
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
result[x + y * width] = (byte)(128 + image[x + y * width] - smooth[x + y * width]);
}
return result;
}