學(xué)習(xí)Halcon的HSmartWindowControl窗口控件,用WPF和Opencv仿照了一個(gè)。
顯示控件的主體是兩個(gè)Canvas: Root Canvas是背景,刷上了網(wǎng)格; 把要顯示的圖像作為Image Canvas的圖像背景,
后面圖像的移動(dòng),縮放,實(shí)質(zhì)都是Image Canvas。
可交互,學(xué)習(xí)的是Halcon的繪圖對(duì)象,WPF的Path來實(shí)現(xiàn)的,Path類有鼠標(biāo)事件,當(dāng)Mouse Enter時(shí),繪圖對(duì)象的線寬增加,離開減少。
protected virtual void _path_MouseMove(object sender, MouseEventArgs e) { }
protected virtual void _path_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_path.Stroke = new SolidColorBrush(_cLineColor);
mbIsSelected = false;
(sender as Path).ReleaseMouseCapture();
}
protected virtual void _path_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){ }
protected virtual void _path_MouseLeave(object sender, MouseEventArgs e)
{
_dLineWidth -= 3;
}
protected virtual void _path_MouseEnter(object sender, MouseEventArgs e)
{
_dLineWidth += 3;
}
protected virtual void UpdateDrawObjectScaleToImageChange() { }
主要實(shí)現(xiàn)了四個(gè)繪圖對(duì)象,其中Rect2DrawingObejct,用的時(shí)Opencv的RotateRect來算的坐標(biāo)(自己算太麻煩了),后期其實(shí)還可以實(shí)現(xiàn)多邊形的繪圖對(duì)象。
至于繪圖對(duì)象的回調(diào)函數(shù),用委托實(shí)現(xiàn):
public delegate void DrawingObjectCallback(string drawingObjectType, DrawingObject drawingObject);
protected DrawingObjectCallback OnDrag;
protected DrawingObjectCallback OnResize;
protected DrawingObjectCallback OnSelect;
至此,整體功能就實(shí)現(xiàn)了。
但是還有一個(gè)問題,就是Image Canvas控件坐標(biāo)和圖像坐標(biāo)的轉(zhuǎn)換,其實(shí)兩個(gè)坐標(biāo)系的轉(zhuǎn)換Factor也很好算:
mdScaleXToImage = mMat.Cols / (value * 1.0);
mdScaleYToImage = mMat.Rows / (value * 1.0);
但是當(dāng)Image Canvas控件的尺寸發(fā)生改變(例如,窗口最大化了)時(shí),這兩個(gè)Factor就也必須更新,對(duì)于控件本身來講,這兩個(gè)值的更新是很容易的,可以在private void imageCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
更新。但在繪圖圖像類中就比較麻煩,目前的做法是繪圖圖像類注冊(cè)了依賴屬性,綁定到窗口相應(yīng)的屬性上,然后在依賴屬性的回調(diào)函數(shù)中去更新繪圖對(duì)象的位置文章來源:http://www.zghlxwxcb.cn/news/detail-407486.html
internal static readonly DependencyProperty ScaleXToImageProperty =
DependencyProperty.Register("ScaleXToImage", typeof(double), typeof(DrawingObject), new PropertyMetadata(1.0, OnScaleToImageChanged));
internal static readonly DependencyProperty ScaleYToImageProperty =
DependencyProperty.Register("ScaleYToImage", typeof(double), typeof(DrawingObject), new PropertyMetadata(1.0, OnScaleToImageChanged));
private static void OnScaleToImageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DrawingObject obj = d as DrawingObject;
if (obj is Rect1DrawingObject)
{
(obj as Rect1DrawingObject).UpdateDrawObjectScaleToImageChange();
}
else if(obj is CircleDrawingObject)
{
(obj as CircleDrawingObject).UpdateDrawObjectScaleToImageChange();
}
else if(obj is LineDrawingObject)
{
(obj as LineDrawingObject).UpdateDrawObjectScaleToImageChange();
}
else if(obj is Rect2DrawingObject)
{
(obj as Rect2DrawingObject).UpdateDrawObjectScaleToImageChange();
}
}
附上demo的效果,也是參考的Halcon&WPF的例程,在Rect1Object的OnDrag回調(diào)函數(shù)中執(zhí)行Sobel元素。文章來源地址http://www.zghlxwxcb.cn/news/detail-407486.html
到了這里,關(guān)于基于WPF Opencv實(shí)現(xiàn)一個(gè)圖像可移動(dòng)、縮放和可交互的顯示窗口的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!