回答
是有一種方法,但它是一個有點亂作爲其基於cvFloodFill操作。現在所有這些算法都是用一種顏色填充一個區域,直到達到類似於區域增長算法的邊緣。爲了有效地使用它,你需要使用一些創新的編碼,但是我警告你這個代碼只是爲了讓你開始,它可能需要重新分解以加快速度。因爲它的循環遍歷每個像素小於255應用cvFloodFill檢查區域是什麼大小,然後如果它在某個區域下面填充它。
重要的是要注意的副本當使用指針時,圖像由提供給cvFloodFill操作的原始圖像組成。如果提供了直接圖像,則最終會出現白色圖像。
OpenFileDialog OpenFile = new OpenFileDialog();
if (OpenFileDialog.ShowDialog() == DialogResult.OK)
{
Image<Bgr, byte> image = new Image<Bgr, byte>(OpenFile.FileName);
for (int i = 0; i < image.Width; i++)
{
for (int j = 0; j < image.Height; j++)
{
if (image.Data[j, i, 0] != 255)
{
Image<Bgr, byte> image_copy = image.Copy();
Image<Gray, byte> mask = new Image<Gray, byte>(image.Width + 2, image.Height + 2);
MCvConnectedComp comp = new MCvConnectedComp();
Point point1 = new Point(i, j);
//CvInvoke.cvFloodFill(
CvInvoke.cvFloodFill(image_copy.Ptr, point1, new MCvScalar(255, 255, 255, 255),
new MCvScalar(0, 0, 0),
new MCvScalar(0, 0, 0), out comp,
Emgu.CV.CvEnum.CONNECTIVITY.EIGHT_CONNECTED,
Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, mask.Ptr);
if (comp.area < 10000)
{
image = image_copy.Copy();
}
}
}
}
}
「新MCvScalar(0,0,0),新MCvScalar(0,0,0),」 不是在這種情況下,真正重要的,因爲你只是在一個二進制圖像的結果填充。 YOu可以與其他設置一起玩,看看你能達到什麼效果。 「如果(comp.area < 10000)」是鍵不斷更改是您要更改該方法將填充的大小洞。
這些是可以預期的結果:
原始
結果
這種方法的問題,我它的內存密集程度非常高,它能夠在200x200的圖像上吞噬6GB的內存,當我嘗試200x300時,它會吞噬所有8GB的內存,並將所有內容都癱瘓。除非你的圖像的大部分是白色的,你想填補微小的空白,或者你可以儘量減少你應用的方法,我會避免它。我會建議編寫自己的類來檢查每個不是255的像素,並添加圍繞它的像素數。然後,您可以記錄不是255的每個像素的位置(在簡單列表中),並且如果您的計數低於閾值,則將圖像中的這些位置設置爲255(通過迭代列表)。
如果你不想自己寫,那麼我會堅持使用Aforge FillHoles類,因爲它是專門爲此目的而設計的。
乾杯
克里斯
想到的問題是有點老了,我想貢獻一個替代解決問題的辦法。
可以得到相同的結果,克里斯沒有記憶的問題,如果您使用以下命令:
private Image<Gray,byte> FillHoles(Image<Gray,byte> image)
{
var resultImage = image.CopyBlank();
Gray gray = new Gray(255);
using (var mem = new MemStorage())
{
for (var contour = image.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP,
mem); contour!= null; contour = contour.HNext)
{
resultImage.Draw(contour, gray, -1);
}
}
return resultImage;
}
關於上述方法的好處是,你可以選擇性地填充孔,以滿足您的標準。例如,您可能要補,孔,其像素數(BLOB中的黑色像素的數量)低於50等
private Image<Gray,byte> FillHoles(Image<Gray,byte> image, int minArea, int maxArea)
{
var resultImage = image.CopyBlank();
Gray gray = new Gray(255);
using (var mem = new MemStorage())
{
for (var contour = image.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP,
mem); contour!= null; contour = contour.HNext)
{
if ((contour.Area < maxArea) && (contour.Area > minArea))
resultImage.Draw(contour, gray, -1);
}
}
return resultImage;
}
我認爲這是最好的答案。 – Rick2047
我也是。以前經常會導致OutOfMemory問題 –
可以使用FillConvexPoly
image.FillConvexPoly(externalContours.ToArray(), new Gray(255));
- 1. Emgu CV SURFFeature Error
- 2. 使用emgu cv
- 3. 使用emgu CV
- 4. 矩形 - Emgu CV
- 5. Emgu CV ColorConversion.RGB2GRAY/BGR2GRAY
- 6. EMGU CV異常
- 7. Emgu CV中的Matrix.Reshape()函數
- 8. Emgu CV中的Alpha混合
- 9. Emgu CV顯示GpuImage
- 10. Emgu CV Blob檢測
- 11. 在emgu cv中重塑
- 12. SVG:用孔填充圖案
- 13. 用孔填充區域
- 14. 自適應孔填充
- 15. 使用Emgu的Background Subtaction cv
- 16. 使用Emgu CV運行相機CV
- 17. 與Emgu CV一起使用Kinect ColorImageFrame CV
- 18. 加載訓練SVM - Emgu CV
- 19. Emgu CV未檢測到CUDA
- 20. 如何使用emgu CV
- 21. 劃分團塊在Emgu CV
- 22. Haar Cascades Emgu CV C#error
- 23. 捕獲RTSP與Emgu CV
- 24. Emgu Cv運動檢測
- 25. Emgu CV微笑檢測
- 26. EMGU CV SURF圖像匹配
- 27. emgu CV C#捕獲類
- 28. Emgu CV中的人像模式
- 29. Emgu CV 3.2.0中的計數器
- 30. Emgu CV - EmguCV中的圖像框架(Skeletonization)
非常感謝克里斯!那就對了 !!! –