2.2.3 C#中显示控件BDPictureBox 的实现----控件实现
1 界面控件布局
2图片内存Mat类说明
- 原始图片:m_raw_mat ,Display_Mat()调用时更新或者InitDisplay_Mat时更新
- 局部放大显示图片:m_extract_zoom_mat,更新scale和scroll信息后更新
- overlay图片 m_extract_overlay_mat , 显示曲线和文本信息
- 最终呈现图片:m_extract_zoom_dispaly
3 正常图片刷新流程举例
视觉检测应用时,为了减少图片刷新次数, 一般只会在最后更新一下图片内存到显示区域,以提高速度,需要用到一个bool类型标志位 b_flush_display
4 滚动条事件代码
/// <summary>
/// hScr0_Scroll
/// remark: 滚动条 hsrco事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void hScr0_Scroll(object sender, EventArgs e)
{double t_gap = DateTime.Now.Subtract(_last_pan).TotalMilliseconds;if (t_gap < 10) return;if (!BD_Window_State_Judge()) return;bd_window_state = BDDISPLAY_STATE.zoom_display;
if (BD_OperateSet.MatisNotNull(m_raw_mat))
{// 计算公式,就是 计算当前 scroll中心相对 scroll原始中心偏移值,然后 修正 画布的放大系数DispManager.get_DispCTX().update_Scroll_Info_after_scroll();OpenCvSharp.Point offset = DispManager.get_DispCTX().getoffset();label_img_info.Text = " X:" + offset.X.ToString("0.0") + " Y:" + offset.Y.ToString("0.0");b_flush_display = false;update_ExtractRGB_and_NewOverlay();b_flush_display = true;Disp_Point_Internal(0, 0, new Scalar(0, 0, 0), 1);b_flush_display = true;
}
bd_window_state = BDDISPLAY_STATE.idle;
_last_pan = DateTime.Now;
}
5 按钮button Zoom事件
/// <summary>
/// btn_zoom_Click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_zoom_Click(object sender, EventArgs e)
{if (!BD_Window_State_Judge()) return;bd_window_state = BDDISPLAY_STATE.zoom_display;try{if (BD_OperateSet.MatisNotNull(m_raw_mat)){DispManager.get_DispCTX().enlarge(1.1f);OpenCvSharp.Point offset = DispManager.get_DispCTX().getoffset();b_flush_display = false;label_img_info.Text = " X:" + offset.X.ToString("0.0") + " Y:"+offset.Y.ToString("0.0");update_ExtractRGB_and_NewOverlay();b_flush_display = true;Disp_Point_Internal(0, 0, new Scalar(0, 0, 0), 1);b_flush_display = false;}}catch (Exception ex){label_img_info.Text = "Zoom:" + ex.Message;}bd_window_state = BDDISPLAY_STATE.idle;
}
6 更新局部图片函数代码update_ExtractRGB_and_NewOverlay
/// <summary>
/// update_ExtractRGB_and_NewOverlay 用于 scale系数变化时用, overlay会清零
/// </summary>
public void update_ExtractRGB_and_NewOverlay()
{ if (!BD_OperateSet.MatisNotNull(m_raw_mat)) return;Mat m_extract_mat_copy = new Mat();try{int nRet = DispManager.get_DispCTX().update_display_img(m_raw_mat,ref hom2d_quick, ref m_extract_zoom_mat); if (nRet != 0) return;#region // 增加显示 多种图片类型 MatType img_type = m_raw_mat.Type();double minVal, maxVal;double scale, add;//step3 m_extract_zoom_dispalywidth_extract_zoom = m_extract_zoom_mat.Width;height_extract_zoom = m_extract_zoom_mat.Height;BD_OperateSet.Assign_Temp(ref m_extract_zoom_overlay, Mat.Zeros(m_extract_zoom_mat.Size(), MatType.CV_8UC3)); switch (img_type.Value){case 0: // CV_8UC1 lock (_object_display){BD_OperateSet.Assign_Temp(ref m_extract_zoom_dispaly, new Mat());Cv2.CvtColor(m_extract_zoom_mat, m_extract_zoom_dispaly, ColorConversionCodes.GRAY2BGR);}break;case 1:break;case 2:// CV_16UC1 case 3://CV_16US1 Cv2.MinMaxIdx(m_raw_mat, out minVal, out maxVal);if ((maxVal - minVal) != 0)scale = (255.0) / (maxVal - minVal);else scale = 1;add = -minVal * scale;lock (_object_display){m_extract_zoom_mat.ConvertTo(m_extract_zoom_mat, MatType.CV_8UC1, scale, add);BD_OperateSet.Assign_Temp(ref m_extract_zoom_dispaly, new Mat());Cv2.CvtColor(m_extract_zoom_mat, m_extract_zoom_dispaly, ColorConversionCodes.GRAY2BGR); }break;case 5:// CV_32FC1 break;case 6:// CV_64FC1 break;case 16: // CV_8UC3 lock (_object_display){ // 销毁内存BD_OperateSet.Assign_Temp(ref m_extract_zoom_dispaly, m_extract_zoom_mat.Clone());}break;case 21: // CV_64FC3 break;default:// 默认显示黑色图片 lock (_object_display){ // 销毁内存BD_OperateSet.Assign_Temp(ref m_extract_zoom_dispaly, new Mat());Cv2.CvtColor(m_extract_zoom_mat, m_extract_zoom_dispaly, ColorConversionCodes.GRAY2BGR); }break;} #endregion}catch (Exception ex){label_img_info.Text = "Update Quick ROI&Img:" + ex.Message;}
}
7 图片显示Display_Mat
public void Display_Mat(ref Mat m_inputimg)
{if (!BD_Window_State_Judge()) return;bd_window_state = BDDISPLAY_STATE.display_mat;try{if (BD_OperateSet.MatisNotNull(m_inputimg)){// 如果 原来图像尺寸和 input尺寸有所变化,需要调用InitDisplay()if(DispManager.get_DispCTX().NeedInitDisplay(m_inputimg.Size(),new OpenCvSharp.Size(pB_Display.Width,pB_Display.Height))){InitDisplay_Mat_Interanl(ref m_inputimg); bd_window_state = BDDISPLAY_STATE.idle; return;} // m_raw_mat = m_inputimg;BD_OperateSet.Assign_Mat(ref m_raw_mat, ref m_inputimg);//n_DisplayMode = 0; if (b_flush_display){update_extract_RGB_And_Overlays();pB_Display.Invalidate();}label_img_info.Text = "Image info:"; }else{}}catch (Exception ex){label_img_info.Text = "Disp Img:" + ex.Message;}bd_window_state = BDDISPLAY_STATE.idle;
}