1+ using System ;
2+ using System . ComponentModel ;
3+ using System . Globalization ;
4+ using System . IO ;
5+ using System . Threading . Tasks ;
6+ using System . Windows . Forms ;
7+
8+ namespace VideoMotionDetect
9+ {
10+ public partial class MainForm : Form
11+ {
12+ private const int STATUS_ITEMS_MAX = 500 ;
13+
14+ private string [ ] m_SelectedVideoFiles = null ;
15+
16+ public MainForm ( )
17+ {
18+ InitializeComponent ( ) ;
19+
20+ totalFilesLabel . Text = string . Empty ;
21+ remainingFilesLabel . Text = string . Empty ;
22+
23+ MotionDetector . LogMessage += LogMessageFromMotionDetection ;
24+ }
25+ private void LogMessageFromMotionDetection ( string msg )
26+ {
27+ statusListBox . InvokeIfRequired ( c =>
28+ {
29+ while ( c . Items . Count > STATUS_ITEMS_MAX )
30+ c . Items . RemoveAt ( statusListBox . Items . Count - 1 ) ;
31+
32+ c . Items . Insert ( 0 , string . Format ( CultureInfo . CurrentCulture ,
33+ "{0:T} {1}" , DateTime . Now , msg ) ) ;
34+ } ) ;
35+ }
36+
37+ private void createMaskButton_Click ( object sender , System . EventArgs e )
38+ {
39+ openFileDialog . Multiselect = false ;
40+
41+ if ( openFileDialog . ShowDialog ( this ) != DialogResult . OK )
42+ return ;
43+
44+ MaskForm mf = null ;
45+
46+ try
47+ {
48+ mf = new MaskForm ( openFileDialog . FileName ) ;
49+ mf . ShowDialog ( this ) ;
50+ }
51+ catch ( Exception ex )
52+ {
53+ MessageBox . Show ( this , string . Format ( CultureInfo . CurrentCulture ,
54+ Properties . Resources . OpenMaskFormError , ex . Message ) ,
55+ this . Text , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
56+ }
57+ finally
58+ {
59+ if ( mf != null )
60+ mf . Dispose ( ) ;
61+ }
62+ }
63+
64+ private void selectVideoFilesButton_Click ( object sender , EventArgs e )
65+ {
66+ openFileDialog . Multiselect = true ;
67+
68+ if ( openFileDialog . ShowDialog ( this ) != DialogResult . OK )
69+ return ;
70+
71+ m_SelectedVideoFiles = openFileDialog . FileNames ;
72+
73+ totalFilesLabel . Text = string . Format ( CultureInfo . CurrentCulture ,
74+ Properties . Resources . FilesSelectedCount ,
75+ m_SelectedVideoFiles . Length ) ;
76+
77+ remainingFilesLabel . Text = string . Empty ;
78+ }
79+
80+ private void backgroundWorker_DoWork ( object sender , DoWorkEventArgs e )
81+ {
82+ DateTime start = DateTime . Now ;
83+
84+ StreamWriter sw = ( StreamWriter ) e . Argument ;
85+ int count = 0 ;
86+
87+ Parallel . ForEach
88+ (
89+ m_SelectedVideoFiles ,
90+ new ParallelOptions ( ) { MaxDegreeOfParallelism = ( int ) parallelismNumericUpDown . Value } ,
91+ videoFile =>
92+ {
93+ int result = - 1 ;
94+
95+ try
96+ {
97+ result = MotionDetector . video_motion_detection ( videoFile ,
98+ ( int ) thresholdNumericUpDown . Value , ( int ) maxDeviationUpDown . Value ,
99+ ( int ) sensitivityUpDown . Value , ( int ) continuationUpDown . Value ,
100+ verboseCheckBox . Checked ) ;
101+ }
102+ catch ( Exception ex )
103+ {
104+ sw . WriteLine ( string . Format ( CultureInfo . InvariantCulture ,
105+ "NG\t {0}\t {1}" , videoFile , ex . ToString ( ) ) ) ;
106+ sw . Flush ( ) ;
107+ }
108+
109+ lock ( sw )
110+ {
111+ sw . WriteLine ( string . Format ( CultureInfo . InvariantCulture , "OK\t {0}\t {1}" , videoFile , result ) ) ;
112+ sw . Flush ( ) ;
113+
114+ count ++ ;
115+
116+ backgroundWorker . ReportProgress
117+ (
118+ count / m_SelectedVideoFiles . Length * 100 ,
119+ m_SelectedVideoFiles . Length - count
120+ ) ;
121+ }
122+ }
123+ ) ;
124+
125+ sw . Close ( ) ;
126+ sw . Dispose ( ) ;
127+
128+ e . Result = start ;
129+ }
130+
131+ private void backgroundWorker_ProgressChanged ( object sender , ProgressChangedEventArgs e )
132+ {
133+ remainingFilesLabel . Text = string . Format ( CultureInfo . CurrentCulture ,
134+ Properties . Resources . FilesRemainingCount , ( int ) e . UserState ) ;
135+ }
136+
137+ private void startButton_Click ( object sender , EventArgs e )
138+ {
139+ if ( m_SelectedVideoFiles == null || m_SelectedVideoFiles . Length == 0 )
140+ {
141+ MessageBox . Show ( this , Properties . Resources . NoVideosMessage ,
142+ this . Text , MessageBoxButtons . OK ) ;
143+
144+ return ;
145+ }
146+
147+ if ( MotionDetector . MotionMask == null || MotionDetector . MotionMask . Empty ( ) )
148+ {
149+ DialogResult ret = MessageBox . Show ( this , Properties . Resources . NoROIMessage ,
150+ this . Text , MessageBoxButtons . YesNo , MessageBoxIcon . Warning ) ;
151+
152+ if ( ret == DialogResult . No )
153+ return ;
154+ }
155+
156+ if ( saveFileDialog . ShowDialog ( this ) != DialogResult . OK )
157+ return ;
158+
159+ StreamWriter sw ;
160+
161+ try
162+ {
163+ sw = File . CreateText ( saveFileDialog . FileName ) ;
164+ }
165+ catch ( Exception ex )
166+ {
167+ MessageBox . Show ( this , string . Format ( CultureInfo . CurrentCulture ,
168+ Properties . Resources . OpenResultFileError , ex . Message ) ,
169+ this . Text , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
170+
171+ return ;
172+ }
173+
174+ remainingFilesLabel . Text = string . Format ( CultureInfo . CurrentCulture ,
175+ Properties . Resources . FilesRemainingCount , m_SelectedVideoFiles . Length ) ;
176+
177+ this . UseWaitCursor = true ;
178+ roiLabel . Enabled = false ;
179+ createMaskButton . Enabled = false ;
180+ selectVideoFilesLabel . Enabled = false ;
181+ selectVideoFilesButton . Enabled = false ;
182+ maxDeviationLabel . Enabled = false ;
183+ maxDeviationUpDown . Enabled = false ;
184+ sensitivityLabel . Enabled = false ;
185+ sensitivityUpDown . Enabled = false ;
186+ continuationLabel . Enabled = false ;
187+ continuationUpDown . Enabled = false ;
188+ parallelismLabel . Enabled = false ;
189+ parallelismNumericUpDown . Enabled = false ;
190+ verboseCheckBox . Enabled = false ;
191+ startButton . Enabled = false ;
192+
193+ NativeMethods . SetThreadExecutionState
194+ (
195+ NativeMethods . EXECUTION_STATE . ES_CONTINUOUS |
196+ NativeMethods . EXECUTION_STATE . ES_SYSTEM_REQUIRED
197+ ) ;
198+
199+ backgroundWorker . RunWorkerAsync ( sw ) ;
200+ }
201+
202+ private void backgroundWorker_RunWorkerCompleted ( object sender , RunWorkerCompletedEventArgs e )
203+ {
204+ this . UseWaitCursor = false ;
205+ roiLabel . Enabled = true ;
206+ createMaskButton . Enabled = true ;
207+ selectVideoFilesLabel . Enabled = true ;
208+ selectVideoFilesButton . Enabled = true ;
209+ maxDeviationLabel . Enabled = true ;
210+ maxDeviationUpDown . Enabled = true ;
211+ sensitivityLabel . Enabled = true ;
212+ sensitivityUpDown . Enabled = true ;
213+ continuationLabel . Enabled = true ;
214+ continuationUpDown . Enabled = true ;
215+ parallelismLabel . Enabled = true ;
216+ parallelismNumericUpDown . Enabled = true ;
217+ verboseCheckBox . Enabled = true ;
218+ startButton . Enabled = true ;
219+
220+ NativeMethods . SetThreadExecutionState ( NativeMethods . EXECUTION_STATE . ES_CONTINUOUS ) ;
221+
222+ if ( e . Error != null )
223+ MessageBox . Show ( this , string . Format ( CultureInfo . CurrentCulture ,
224+ Properties . Resources . BackgroundWorkerError , e . Error . ToString ( ) ) ,
225+ this . Text , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
226+
227+ MessageBox . Show ( this , string . Format ( CultureInfo . CurrentCulture ,
228+ Properties . Resources . Finished , DateTime . Now . Subtract ( ( DateTime ) e . Result ) ) ,
229+ Properties . Resources . FinishedTitle , MessageBoxButtons . OK , MessageBoxIcon . None ) ;
230+ }
231+ }
232+ }
0 commit comments