c# - Resfresh twice picturebox show Errorimage -
c# - Resfresh twice picturebox show Errorimage -
i write videobox class show images capture video file or webcam using opencv code in c++, need fixed size box override minimum , maximum
public ref class videobox : public system::windows::forms::picturebox { public: videobox(); ~videobox(); bool capture() { cv::mat cur_frame; bool r = maintracker.capture(cur_frame); if(!r) homecoming r; imshow("debug window", cur_frame); this->image = gcnew system::drawing::bitmap(cur_frame.cols, cur_frame.rows, cur_frame.step, system::drawing::imaging::pixelformat::format24bpprgb, (system::intptr)cur_frame.ptr()); this->refresh(); homecoming true; } .... virtual property system::drawing::size minimumsize { system::drawing::size get() override { homecoming m_desiredsize; } void set(system::drawing::size) override { } } virtual property system::drawing::size maximumsize { system::drawing::size get() override { homecoming m_desiredsize; } void set(system::drawing::size) override { } } protected: /* virtual void onpaint(system::windows::forms::painteventargs^ pe) override { picturebox::onpaint(pe); }*/ private: system::drawing::size m_desiredsize; };
and c# class inherit videobox
public class video : videobox { public enum drawmode { draw_h_line, draw_v_line, draw_rect, none }; public enum showmode { show_user_rects, show_user_lines, hide_all, show_all }; public video() { b_drawrect = b_drawhline = b_drawvline = false; lstbrush = new hatchbrush(hatchstyle.backwarddiagonal, color.green, color.transparent); ctimer = new timer(); ctimer.interval = 100; // msec alter frame in video mode ctimer.tick += new eventhandler(ctimer_tick); // if uncomment can see image on design mode :d //setcapturevideo(); m_drmode = drawmode.draw_rect; m_userrects = new list<rectangle>(); } public void setcapturevideo() { ... } public void startvideo() { ctimer.start(); } public void stopvideo() { ctimer.stop(); } private void ctimer_tick(object sender, eventargs e) { capture(); } //protected override void onpaint(painteventargs e) //{ // base.onpaint(e); // graphics g = e.graphics; // if (m_insertrect.width > 0 && b_drawrect) // { // pen mp = new pen(color.green); // g.drawrectangle(mp, m_insertrect); // } // if (m_shmode == showmode.show_user_rects || m_shmode == showmode.show_all) // { // font drawfont = new font("arial",8 ); // solidbrush drawbrush = new solidbrush(color.red); // // set format of string. // stringformat drawformat = new stringformat(); // if(m_userrects.count > 0) // { // int c=1; // foreach(rectangle rect in m_userrects) // { // g.fillrectangle(lstbrush, rect); // g.drawstring(c.tostring(), drawfont, drawbrush, rect.location, drawformat); // c++; // } // } // } //} protected override void onmousemove(mouseeventargs e) { base.onmousemove(e); if (e.button == system.windows.forms.mousebuttons.left) { if (m_drmode == drawmode.draw_rect && !m_firstp.isempty) { b_drawrect = true; float x = m_firstp.x < e.x ? m_firstp.x : e.x; float y = m_firstp.y < e.y ? m_firstp.y : e.y; float w = math.abs(m_firstp.x - e.x); float h = math.abs(m_firstp.y - e.y); m_insertrect = new rectangle((int)x, (int)y, (int)w, (int)h); if (!ctimer.enabled) this.refresh(); } } if(m_drmode == drawmode.draw_h_line && !m_firstp.isempty) { m_hlinep = e.location; b_drawhline = true; if(!ctimer.enabled) this.refresh(); } else if (m_drmode == drawmode.draw_v_line && !m_firstp.isempty) { m_vlinep = e.location; b_drawvline = true; if (!ctimer.enabled) this.refresh(); } } protected override void onmousedown(mouseeventargs e) { base.onmousedown(e); if (b_drawvline) { b_drawvline = false; m_vlinep = e.location; m_drmode = drawmode.none; } else if (b_drawhline) { b_drawhline = false; m_hlinep = e.location; m_drmode = drawmode.none; } else m_firstp = e.location; } protected override void onmouseup(mouseeventargs e) { base.onmouseup(e); if (m_drmode == drawmode.draw_rect) { if (b_drawrect) { m_userrects.add(m_insertrect); b_drawrect = false; if (!ctimer.enabled) this.refresh(); } } } // private members private list<rectangle> m_userrects; private timer ctimer; private pointf m_firstp; private pointf m_hlinep, m_vlinep; private rectangle m_insertrect; private bool b_drawrect, b_drawhline, b_drawvline; private hatchbrush lstbrush; private showmode m_shmode; private drawmode m_drmode; }
if resize form many times videobox show errorimage of picturebox
if refresh video box when ctimer enabled shows errorimage again
imshow works without problem
where problem think??
first, word of caution: opencv, beingness raii based, , managed c++ not go together.
you allocate local mat in capture function:
bool capture() { cv::mat cur_frame; ...
this release/invalidate info pointer, 1 time goes out of scope (when leaving capture()) , imagebox left invalid/dangling pointer.
so, have maintain cv::mat cur_frame live whole duration of program, here gets pretty ugly:
public: cv::mat *cur_frame; // yep, bloody *pointer*, stupid managed c++ can't raii... videobox() { cur_frame = new mat(); } ~videobox() { delete cur_frame; } bool capture() { bool r = maintracker.capture( *cur_frame ); // deref if(!r) homecoming r; imshow("debug window", *cur_frame); this->image = gcnew system::drawing::bitmap(cur_frame->cols, cur_frame->rows, cur_frame->step, system::drawing::imaging::pixelformat::format24bpprgb, (system::intptr)cur_frame->ptr()); this->refresh(); homecoming true; }
c# .net opencv c++-cli
Comments
Post a Comment