public Bgra32Image HistogramEqualization() { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.histogram_equalization(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height); this.imgPixels = buffer; return(this); }
public Bgra32Image BilinearTransform(double deltaX, double deltaY, double angle, double scale) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.bilinear_transform(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, (float)deltaX, (float)deltaY, (float)angle, (float)scale); this.imgPixels = buffer; return(this); }
public Bgra32Image Quantize(uint lv) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.quantize(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, lv); this.imgPixels = buffer; return(this); }
public Gray8Image MorphologyCorrode() { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.morphology_corrode(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height); this.imgPixels = buffer; return(this); }
public Bgra32Image Sample(uint rate) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.sample(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, rate); this.imgPixels = buffer; return(this); }
public Gray8Image GrayProcessing(uint bit) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.mask(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, bit); this.imgPixels = buffer; return(this); }
public static string Bitmap2string(BitmapSource img) { /* 转换图片为灰度图并拆分为数组 */ var gray8_img = new Gray8Image(img); var pixels = gray8_img.ImagePixels; var info = gray8_img.Info; /* 转换图片像素数组转化为字符画 */ /* 如果 buffer 长度不够,将不会执行转换 */ var length = (uint)((info.Width + 2) * (info.Height >> 1)); var buffer = new byte[length]; ImgFunc.img2txt(pixels, (uint)info.Width, (uint)info.Height, buffer, ref length); /* * [How to convert byte[] to string?](http://stackoverflow.com/questions/1003275/how-to-convert-byte-to-string) */ var ret = System.Text.Encoding.UTF8.GetString(buffer, 0, (int)length); return(ret); }
public Gray8Image ContrastStretching(float a, float b) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.contrast_stretching(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, a, b); this.imgPixels = buffer; return(this); }
public Gray8Image LogarithmicTransformation(float c, float v) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.logarithmic_transformation(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, c, v); this.imgPixels = buffer; return(this); }
public Gray8Image GammaCorrection(float r, float eps) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.gamma_correction(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, r, eps); this.imgPixels = buffer; return(this); }
public Gray8Image Threshold(uint min, uint max) { byte[] buffer = new byte[imgPixels.Length]; ImgFunc.threshold(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, min, max); this.imgPixels = buffer; return(this); }
private void LoadImg(BitmapSource img) { /* * 笔记: * * 最开始尝试使用 System.drawing 实现转换为 byte,想了想还是算了(各种转化),这些是当时的资料 * 参考资料: * [Convert a bitmap into a byte array](http://stackoverflow.com/questions/7350679/convert-a-bitmap-into-a-byte-array?lq=1) * [System.drawing namespace not found under console application](http://stackoverflow.com/questions/8553136/system-drawing-namespace-not-found-under-console-application) * * 最后决定还是直接转换 BitmapImage 到 byte[] * * 然后翻了一下这个 [BitmapImage to byte[]](http://stackoverflow.com/questions/6597676/bitmapimage-to-byte) * (虽然最后并没有用上,但是知道了如何转换 BitmapImage 的格式) * * 最后,参考资料: * [Finding specific pixel colors of a BitmapImage](http://stackoverflow.com/questions/1176910/finding-specific-pixel-colors-of-a-bitmapimage) * 这里强行把图片换成了 PixelFormats.Bgra32,同时使用 CopyPixels 获取各个像素信息到 byte[] 中, * 这样就可以交给外部方法处理了。 */ /* 保存 Bgra32 版本的像素 */ bgraImgSrc = new Bgra32Image(img); //BgraImgNow = new Bgra32Image(BgraImgSrc); /* 保存 8bit 灰度图的版本 */ gray8ImgSrc = new Gray8Image(img); /* 根据图片大小,确定是否实时计算 */ realtimeProcessing = (img.PixelWidth * img.PixelHeight) < (imgWidMax * imgHgtMax); /* 确定采样的上限值 */ sliderSampling.Maximum = Math.Max(img.PixelWidth, img.PixelHeight); /* 调整窗口大小 */ ResizeForImg(this.imgSrc); /* 显示原图像 */ OriginImg(this.imgSrc); /* 启用 保存 按钮 */ try { if (ImgFunc.is_loaded()) { EnbaleComponent(); } /* 刷新直方图 */ UpdateHistogram(); } catch (Exception e) { MessageBox.Show( e.Message, "加载 ImgFuncLib 时发生错误", MessageBoxButton.OK, MessageBoxImage.Error ); } }
/**************** 以上是 频域滤波 的处理部分 ****************/ /**************** 以下是 选项卡切换选项 的处理部分 ****************/ /* * 参考资料: * 响应,切换选项卡: * [Is there Selected Tab Changed Event in the standard WPF Tab Control](http://stackoverflow.com/questions/772841/is-there-selected-tab-changed-event-in-the-standard-wpf-tab-control) */ private void tabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (!(e.Source is TabControl) || this.imgSrc == null) { return; } if (tabItem_Origin.IsSelected) { OriginImg(this.imgSrc); } else if (tabItem_Quantization.IsSelected) { this.imageView.Source = this.imgRes = new Bgra32Image(this.bgraImgSrc).Quantize((uint)this.sliderQuantization.Value).ToBitmapSource(); } else if (tabItem_Sampling.IsSelected) { this.imageView.Source = this.imgRes = new Bgra32Image(this.bgraImgSrc).Sample((uint)this.sliderSampling.Value).ToBitmapSource(); } else if (tabItem_Binary.IsSelected) { this.imageView.Source = this.imgRes = new Gray8Image(this.gray8ImgSrc).GrayProcessing((uint)this.sliderGray8.Value).ToBitmapSource(); } else if (tabItem_Img2txt.IsSelected) { this.imgTxt = ImgFunc.Bitmap2string(this.imgRes); } else if (tabItem_PointOps.IsSelected) { this.imageView.Source = this.imgRes = new Gray8Image(this.gray8ImgSrc).GrayProcessing(0).ToBitmapSource(); } else if (tabItem_HistogramEqualization.IsSelected) { this.imageView.Source = this.imgRes = new Bgra32Image(this.bgraImgSrc).HistogramEqualization().ToBitmapSource(); } else if (tabItem_Transform.IsSelected) { this.TransformReset(); } else if (tabItem_Filter.IsSelected) { /* 更新 数据表格 */ datagrid_FilterMatrix.ItemsSource = ImgFunc.ConvertArray2DToDataTable(filter_matrix).AsDataView(); } UpdateHistogram(); }
private void datagrid_FilterMatrix_CurrentCellChanged(object sender, EventArgs e) { /* * [Convert and use DataTable in WPF DataGrid?] * (http://stackoverflow.com/questions/6984686/convert-and-use-datatable-in-wpf-datagrid) */ var table = ((DataView)datagrid_FilterMatrix.ItemsSource).ToTable(); filter_matrix = ImgFunc.ConvertDataTableToArray2D <double>(table); if (realtimeProcessing) { buttonFilterCalc_Click(null, null); } }
public Gray8Image Histogram(out ImageSource histogram, out int mean, out int mid, out int sd, out int sum) { var cnt = new uint[256u]; var data = new uint[4u]; ImgFunc.histogram(imgPixels, (uint)imgInfo.Width, (uint)imgInfo.Height, cnt, data); histogram = ImgFunc.GenerateHistogram(cnt); /* data[] 分别:{灰度均值,灰度中值,灰度方差,像素总数} */ mean = (int)data[0]; mid = (int)data[1]; sd = (int)data[2]; sum = (int)data[3]; return(this); }
public Bgra32Image Filter(string opName) { var buffer = new byte[imgPixels.Length]; switch (opName) { case "roberts": ImgFunc.filter_roberts(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height); break; case "sobel": ImgFunc.filter_sobel(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height); break; case "median": ImgFunc.filter_median(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height); break; default: throw new Exception("No such Filter!"); } this.imgPixels = buffer; return(this); }
private void buttonFilter_Click(object sender, RoutedEventArgs e) { if (!(e.Source is Button)) { return; } if (e.Source == button_FilterIncreaseCol) { filter_matrix_wid += 2; if (filter_matrix_wid > 1) { button_FilterReduceCol.IsEnabled = true; } } else if (e.Source == button_FilterReduceCol) { filter_matrix_wid -= 2; if (filter_matrix_wid <= 1) { button_FilterReduceCol.IsEnabled = false; } } else if (e.Source == button_FilterIncreaseRow) { filter_matrix_hgt += 2; if (filter_matrix_hgt > 1) { button_FilterReduceRow.IsEnabled = true; } } else if (e.Source == button_FilterReduceRow) { filter_matrix_hgt -= 2; if (filter_matrix_hgt <= 1) { button_FilterReduceRow.IsEnabled = false; } } filter_matrix = ImgFunc.ResizeArray2D(filter_matrix, filter_matrix_wid, filter_matrix_hgt); datagrid_FilterMatrix.ItemsSource = ImgFunc.ConvertArray2DToDataTable(filter_matrix).AsDataView(); }
public Bgra32Image Filter(float[] mat, uint wid, uint hgt) { /* 针对 int 版本的优化(不过可能没什么明显价值?) */ bool allInteger = true; foreach (var num in mat) { /* [How to determine if a decimal/double is an integer?] * (http://stackoverflow.com/questions/2751593/how-to-determine-if-a-decimal-double-is-an-integer) */ if (num % 1 != 0) { allInteger = false; break; } } var buffer = new byte[imgPixels.Length]; if (allInteger) { var int_matrix = new int[mat.Length]; for (int i = 0; i < mat.Length; i++) { int_matrix[i] = (int)mat[i]; } ImgFunc.filter(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, int_matrix, wid, hgt); } else { ImgFunc.filter(imgPixels, buffer, (uint)imgInfo.Width, (uint)imgInfo.Height, mat, wid, hgt); } this.imgPixels = buffer; return(this); }
private void comboBox_Filter_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.Source == comboBox_Filter) { switch (comboBox_Filter.SelectedIndex) { case 0: { filter_matrix = new double[, ] { { 0, -1, 0 }, { -1, 4, -1 }, { 0, -1, 0 }, }; break; } case 1: { filter_matrix = new double[, ] { { 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0 }, { 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0 }, { 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0 }, }; break; } case 2: { filter_matrix = new double[, ] { { 1 / 10.0, 1 / 10.0, 1 / 10.0 }, { 1 / 10.0, 2 / 10.0, 1 / 10.0 }, { 1 / 10.0, 1 / 10.0, 1 / 10.0 }, }; break; } case 3: { filter_matrix = new double[, ] { { 1 / 16.0, 1 / 8.0, 1 / 16.0 }, { 1 / 8.0, 1 / 4.0, 1 / 8.0 }, { 1 / 16.0, 1 / 8.0, 1 / 16.0 }, }; break; } case 4: { filter_matrix = new double[, ] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 }, }; break; } case 5: { filter_matrix = new double[, ] { { -1, -1, -1 }, { -1, 9, -1 }, { -1, -1, -1 }, }; break; } case 6: { filter_matrix = new double[, ] { { 1, -2, 1 }, { -2, 5, -2 }, { 1, -2, 1 }, }; break; } case 7: { filter_matrix = new double[, ] { { 0, 0, 0 }, { -1, 1, 0 }, { 0, 0, 0 }, }; break; } case 8: { filter_matrix = new double[, ] { { 0, -1, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, }; break; } case 9: { filter_matrix = new double[, ] { { -1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, }; break; } case 10: { filter_matrix = new double[, ] { { -1, -1, -1, -1, -1 }, { 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1 }, }; break; } case 11: { filter_matrix = new double[, ] { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 }, }; break; } case 12: { filter_matrix = new double[, ] { { -1, 0, -1 }, { 0, 4, 0 }, { -1, 0, -1 }, }; break; } case 13: { filter_matrix = new double[, ] { { -1, -1, -1 }, { -1, 8, -1 }, { -1, -1, -1 }, }; break; } case 14: { filter_matrix = new double[, ] { { -1, -1, -1 }, { -1, 9, -1 }, { -1, -1, -1 }, }; break; } case 15: { filter_matrix = new double[, ] { { 1, -2, -1 }, { -2, 4, -2 }, { 1, -2, -1 }, }; break; } default: break; } datagrid_FilterMatrix.ItemsSource = ImgFunc.ConvertArray2DToDataTable(filter_matrix).AsDataView(); if (realtimeProcessing) { buttonFilterCalc_Click(null, null); } } else if (e.Source == comboBox_FilterOther) { BitmapSource img = null; switch (comboBox_FilterOther.SelectedIndex) { case 0: img = new Bgra32Image(this.bgraImgSrc).Filter("median").ToBitmapSource(); break; case 1: img = new Bgra32Image(this.bgraImgSrc).Filter("roberts").ToBitmapSource(); break; case 2: img = new Bgra32Image(this.bgraImgSrc).Filter("sobel").ToBitmapSource(); break; } if (img != null) { this.imageView.Source = this.imgRes = img; } } }
public static BitmapImage OpenImgFileWithHuffmanCoding(string filePath = null) { if (filePath == null) { var dlg = new Microsoft.Win32.OpenFileDialog() { DefaultExt = "*.hfm", Filter = "Binary File with Huffman Coding (*.hfm)|*.hfm" }; if ((bool)dlg.ShowDialog()) { filePath = dlg.FileName; } } if (filePath != null) { /* * 参考资料: * [BitmapImage sourceStream is null in WPF] * (http://stackoverflow.com/questions/17838006/bitmapimage-sourcestream-is-null-in-wpf) */ byte[] src = File.ReadAllBytes(filePath); /* 转换结果 */ var buf = new byte[src.Length * 8]; var actual_size = ImgFunc.huffman_decode(src, (uint)src.Length, buf, (uint)buf.Length); /* 检查转换是否出现错误 */ if (actual_size < 0) { string message; switch (actual_size) { case -1: { message = "这不是一个有效的哈夫曼压缩文件"; break; } case -2: { message = "无法建立哈夫曼树进行解码"; break; } case -3: { message = "解码所分配的缓冲区不足,无法继续解码"; break; } case -4: { message = "文件数据不完整,无法继续解码"; break; } default: { message = "未知的错误"; break; } } System.Windows.MessageBox.Show( message, "无法打开文件", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error ); return(null); } var img = new BitmapImage(); try { /* 尝试初始化图像 */ img.BeginInit(); img.StreamSource = new MemoryStream(buf, 0, actual_size); img.EndInit(); } catch (System.InvalidOperationException) { System.Windows.MessageBox.Show( "未能识别这个文件类型", "不支持的文件", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error ); img = null; } return(img); } return(null); }
public static void SaveImgFileWithHuffmanCoding(BitmapSource img) { /* * 关于转换方法: * [Data type conversion: BitmapImage to binary or byte[]] * (https://social.msdn.microsoft.com/Forums/vstudio/en-US/a47b89c0-b1a2-4212-96bb-63e4d9cbe319/data-type-conversion-bitmapimage-to-binary-or-byte?forum=netfxbcl) */ byte[] buf; int actual_size; { /* 开始转换 */ byte[] src; BmpBitmapEncoder encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(img)); using (MemoryStream ms = new MemoryStream()) { encoder.Save(ms); src = ms.ToArray(); } /* 转换结果 */ buf = new byte[src.Length + 4096]; actual_size = ImgFunc.huffman_encode(src, (uint)src.Length, buf, (uint)buf.Length); /* 检查转换是否出现错误 */ if (actual_size < 0) { string message; switch (actual_size) { case -3: case -1: { message = "内部错误,缓冲区分配不足"; break; } case -2: { message = "内部错误,创建哈夫曼树失败"; break; } default: { message = "未知的错误"; break; } } System.Windows.MessageBox.Show( message, "保存文件失败", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error ); return; } } var dlg = new Microsoft.Win32.SaveFileDialog() { DefaultExt = "*.hfm", Filter = "Binary File with Huffman Coding (*.hfm)|*.hfm" }; var result = dlg.ShowDialog(); if (result == true) { var fs = File.Open(dlg.FileName, FileMode.Create); fs.Write(buf, 0, actual_size); fs.Close(); } }