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_dispaly
width_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;
}