如何用EmguCV处理原始字节图像阈值?遇CV_8UC1异常求助
问题原因
异常OpenCv: src.type() == CV_8UC1说明自适应阈值方法ThresholdAdaptive要求输入图像必须是8位无符号单通道(CV_8UC1),但你代码中使用的iimg是Image<Gray, ushort>类型(16位无符号单通道),类型不兼容导致报错。
另外代码还有两个潜在问题:
- 初始化
Image<Gray, ushort>后直接赋值Bytes属性:ushort类型每个像素占2字节,但你读取的pixelData_是byte数组(每个像素1字节),会导致数据解析错误。 Split('\')中的反斜杠未转义,应该写成Split('\\'),否则无法通过编译。
解决方案
根据你的场景,有两种可行的修复方式:
方式一:直接使用8位图像(推荐,因为你读取的是byte类型像素数据)
将图像初始化改为Image<Gray, byte>,从根源匹配阈值方法的类型要求:
var pixelData_ = dataset.GetValues<byte>(DicomTag.PixelData); // 修正反斜杠转义 var splitPixelSpacing = pixelSpacing.Split('\\'); var IPP = dataset.GetString(DicomTag.ImagePositionPatient); // 改为创建8位单通道图像 var iimg = new Image<Gray, byte>(cols, rows); var parse = float.Parse(splitPixelSpacing[0], CultureInfo.InvariantCulture.NumberFormat); var newPixelSpacing = parse * (cols / 512); iimg.Bytes = pixelData_; iimg = iimg.Resize(512, 512, Inter.Area); var imgBin = new Image<Gray, byte>(512, 512, new Gray(10)); // 现在可以正常调用ThresholdAdaptive var blr = iimg.ThresholdAdaptive(new Gray(100), AdaptiveThresholdType.GaussianC, ThresholdType.ToZero, 5, new Gray(2));
方式二:若需处理16位图像,先转换为8位
如果你的DICOM实际存储的是16位像素数据(此时应该用GetValues<ushort>读取),需要先将16位图像转换为8位后再调用阈值方法:
// 假设读取16位像素数据 var pixelData_ = dataset.GetValues<ushort>(DicomTag.PixelData); var splitPixelSpacing = pixelSpacing.Split('\\'); var IPP = dataset.GetString(DicomTag.ImagePositionPatient); var iimg = new Image<Gray, ushort>(cols, rows); // 16位图像建议通过Data属性赋值(需将一维数组转为二维) for (int y = 0; y < rows; y++) { for (int x = 0; x < cols; x++) { iimg.Data[y, x, 0] = pixelData_[y * cols + x]; } } iimg = iimg.Resize(512, 512, Inter.Area); // 将16位图像转换为8位(自动缩放像素值到0-255范围) var img8Bit = iimg.Convert<Gray, byte>(); var imgBin = new Image<Gray, byte>(512, 512, new Gray(10)); // 对8位图像调用阈值方法 var blr = img8Bit.ThresholdAdaptive(new Gray(100), AdaptiveThresholdType.GaussianC, ThresholdType.ToZero, 5, new Gray(2));
内容的提问来源于stack exchange,提问作者Anasse
相关产品推荐
相关产品推荐

