Meteor2/4와 Meteor2/MC 차이점.

Meteor2/4와 Meteor2/MC는 두 보드 모두 아날로그카메라를 대상으
로 한다는 점에 공통점이 있습니다.
하지만, Meteor2/4와 Meteor2/MC 보드의 차이는 다음과 같습니다.

첫째로 하나는 지원하는 영상입력신호의 종류가 Meteor2/4는 표준
아날로그입력신호인 RS170(흑백), NTSC(칼라)(혹은 CCIR, PAL)만을
지원하는 반면 Meteor2/MC는 이러한 표준신호들외에 Progressive
Signal(아날로그표준들은 모두 Interlaced방식인건 아시죠?^^)을 지
원하고 표준에서 제한되는 640*480의 해상도만이 아니라 다른 비표
준해상도를 사용할수가 있다는 장점이 있습니다. 물론 카메라에 따
라서 달라지겠죠..

둘째로는 두대 이상의 카메라로 동시Grab을 할수 있느냐 하는 것입
니다. 카메라를 사용하는 용도에 따라서는 동시에 찍어야 할 때가
있고, 카메라를 Switching하면서 같이 사용해도 되는 경우가 있습니
다. Meteor2/4는 최대 12대의 흑백카메라를 스위칭하여 사용할수 있
는 반면 동시그랩은 할 수 없습니다. 하지만, Meteor2/MC보드는 MC
가 Multi-Channel의 약자인것에서 볼수 있듯이 흑백카메라 3대를 동
시에 그랩할 수 있습니다. RGB 카메라의 경우는 두대를 스위칭할
수 있고, 흑백카메라는 최대 6대를 스위칭할 수가 있습니다.

간단히 말하면 Meteor2/MC는 Meteor2/4가 사용될수 있는 거의 모든
경우에 사용할수가 있죠(케이블에 있어서 차이는 있습니다.), 그러
나 Meteor2/MC보드를 사용해야 하는 예로는 다음과 같은 경우가 있
습니다.

- 카메라의 영상신호방식이 표준을 따르지 않는 경우
'Progressive방식을 사용하는 경우
'해상도가 640*480이 아닌 경우
'영상신호의 초당 프레임수가 30프레임(60필드)이 아닌경우

- 카메라의 동시그랩을 원할 때
'흑백카메라 최대 3대 동시그랩
(칼라카메라동시그랩이 되는 Matrox제품은 현재 출시되어
있지 않습니다.)

 

'영상처리 > 기타' 카테고리의 다른 글

프레임 심도의 중요성 (영상심도)  (0) 2014.11.06
렌즈 배율별 광량차이  (0) 2014.10.13

목적: Hitachi CCD Camera 사용(FD-202SCL)

원인: 본 카메라는 3CCD Camera로써, BayFilger가 존재하지 않지만,

해당 소스에서 BayBuf를 사용하여 흑백으로 화면이 표시됨.

해결: MbufBayer -> 사용하지 않음

 

문제부 소스

////////////////////////////////////////////////////////////////////////////////////////////////

// FD-202SCL is 3CCD Camera system. It has a 3CCD Camera type. So It haven't bayer filter.
// If you want to use for your ccd image, you don't need to MBufBayer function in MIL Library.
#ifdef _FD_202SCL_HITACHI_CCD_CAMERA
// not use.
#else
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType+M_WHITE_BALANCE_CALCULATE);
EnterCriticalSection(&g_csWhiteBalance);

#ifdef _MIL_90
if(pDlg->m_bUse_AVERAGE_2X2)
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType/* +M_AVERAGE_2X2*/);
else
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType +M_ADAPTIVE);
#else
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType +M_ADAPTIVE);
#endif
LeaveCriticalSection(&g_csWhiteBalance);
#endif

/////////////////////////////////////////////////////////////////////////////////////////////////////////

 

해당 소스부 .h

1. MIL_ID m_MilIdImg; // Image buffer identifier

 

.cpp

m_MilIdImg = M_NULL; // Image buffer identifier

MbufClear(m_MilIdImg, 0);

 

// Solios 사용.

pSystem = "\\\\.\\M_SYSTEM_SOLIOS ;

 

// Main Mil Sys 할당

MsysAlloc((char*)pSystem, M_DEF_SYSTEM_NUM, M_COMPLETE | M_DDRAW, &m_MilIdSys);

 

MdigControl(m_MilIdDig, M_GRAB_MODE, M_ASYNCHRONOUS); //must M_ASYNCHRONOUS

MdigControl(m_MilIdDig, M_GRAB_TIMEOUT , 1000);

 

MdigHookFunction(m_MilIdDig, M_GRAB_START, HookFrameEnd, (void *)(this)); // 데이터 취득 함수설정
MdigHookFunction(m_MilIdDig, M_GRAB_END, HookGrabEnd, (void *)(this)); // 취득 함수 설정

 

// 3 band (r,G,B) grab x/y size 설정, MildImg 저장.

MbufAllocColor(m_MilIdSys, 3, m_nGrabSizeX, m_nGrabSizeY, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &m_MilIdImg);

 

//Allocate from dcf file. szDCFFile = Camera 사용 DCF files.
MdigAlloc(m_MilIdSys, M_DEFAULT, (MIL_TEXT_PTR)szDCFFile, M_DEFAULT, &m_MilIdDig);

 

// band acquire

long band ;
band = MdigInquire(m_MilIdDig, M_SIZE_BAND, M_NULL);

 

// mil 데이터 취득.

#ifdef _FD_202SCL_HITACHI_CCD_CAMERA
MdigGrab(pDlg->m_MilIdDig, pDlg->m_MilIdImg);
#else
MdigGrab(pDlg->m_MilIdDig, pDlg->m_MilIdImgField[g_nBufIndex]);
#endif

C# System Event 사용방안.

발췌 : http://www.daveoncsharp.com/2009/10/how-to-capture-system-events-using-csharp/

How to Capture System Events using C#

by Dave on October 5, 2009

in Operating System

What are system events? Well, basically they are events raised by the operating system when a user performs an action which affects the operating environment.

System events are accessible through the Microsoft.Win32.SystemEvents class.

SystemEvents Events

Below is a list of all the system events found within the SystemEvents class.

Name Description
DisplaySettingsChanged Occurs when the user changes the display settings.
DisplaySettingsChanging Occurs when the display settings are changing.
EventsThreadShutdown Occurs before the thread that listens for system events is terminated.
InstalledFontsChanged Occurs when the user adds fonts to or removes fonts from the system.
LowMemory Obsolete. Occurs when the system is running out of available RAM.
PaletteChanged Occurs when the user switches to an application that uses a different palette.
PowerModeChanged Occurs when the user suspends or resumes the system.
SessionEnded Occurs when the user is logging off or shutting down the system.
SessionEnding Occurs when the user is trying to log off or shut down the system.
SessionSwitch Occurs when the currently logged-in user has changed.
TimeChanged Occurs when the user changes the time on the system clock.
TimerElapsed Occurs when a windows timer interval has expired.
UserPreferenceChanged Occurs when a user preference has changed.
UserPreferenceChanging Occurs when a user preference is changing.

Note: Some of these system events may not be raised on Windows Vista.

Example Application

As an example let’s create a simple Windows Forms Application and place two buttons and a textbox on the main form. The buttons are going to subscribe and unsubscribe from the system events and the textbox is going to display the captured event details.

In our application we are going to listen for the following four system events: InstalledFontsChanged, DisplaySettingsChanged, TimeChanged, and UserPreferenceChanged. The code for this is shown below:

private bool eventHandlersCreated;

private void btnStartListening_Click(object sender, EventArgs e)
{
    this.StartListening();
}

private void btnStopListening_Click(object sender, EventArgs e)
{
    this.StopListening();
}

private void StartListening()
{
    Microsoft.Win32.SystemEvents.InstalledFontsChanged += new EventHandler(FontHandler);
    Microsoft.Win32.SystemEvents.DisplaySettingsChanged += new EventHandler(ScreenHandler);
    Microsoft.Win32.SystemEvents.TimeChanged += new EventHandler(TimeHandler);
    Microsoft.Win32.SystemEvents.UserPreferenceChanged += new Microsoft.Win32.UserPreferenceChangedEventHandler(PreferenceChangedHandler);

    this.eventHandlersCreated = true;
}

private void StopListening()
{
    Microsoft.Win32.SystemEvents.InstalledFontsChanged -= new EventHandler(FontHandler);
    Microsoft.Win32.SystemEvents.DisplaySettingsChanged -= new EventHandler(ScreenHandler);
    Microsoft.Win32.SystemEvents.TimeChanged -= new EventHandler(TimeHandler);
    Microsoft.Win32.SystemEvents.UserPreferenceChanged -= new Microsoft.Win32.UserPreferenceChangedEventHandler(PreferenceChangedHandler);

    this.eventHandlersCreated = false;
}

As you can see in the StartListening and StopListening methods we are subscribing and unsibscribing to the system events. Each event handler delegate is calling a particular method, and these methods are shown below:

private void FontHandler(object sender, EventArgs e)
{
    txtStatus.Text += string.Format("Installed fonts changed. {0}", Environment.NewLine);
}

private void PreferenceChangedHandler(object sender, Microsoft.Win32.UserPreferenceChangedEventArgs e)
{
    txtStatus.Text += string.Format("You changed a setting: {0} {1}", e.Category.ToString(), Environment.NewLine);
}

private void ScreenHandler(object sender, EventArgs e)
{
    txtStatus.Text += string.Format("Screen resolution changed. {0}", Environment.NewLine);
}

private void TimeHandler(object sender, EventArgs e)
{
    txtStatus.Text += string.Format("System time changed. {0}", Environment.NewLine);
}

If you were to run this application and then go and change the screen resolution for example, the DisplaySettingsChanged event will fire and its delegate will call our ScreenHandler method, and you will see the text Screen resolution changed in the textbox.

Below is a screenshot of our application:

 

 

Note: Since these system events are static events, you must make sure you detach your event handlers when disposing your application, or you will end up with memory leaks!

To take care of this memory leak potential problem, when closing our application we are calling the StopListening method to unsubscribe from the event handlers.

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.eventHandlersCreated)
        this.StopListening();
}

Another Note: Do not perform time-consuming processing on the same thread that raises a system event handler because it might prevent other applications from functioning.

If your application must perform time-consuming processes, do the processing on a separate worker thread and not on the same thread which raises the system events. If you want more information on worker threads you can have a look at my articles – Create a Worker Thread for your Windows Form in C# and Using the BackgroundWorker Component in C#.

I hope you found this useful. Thanks for reading.

Dave

 

문자열 취득 후 한글자씩. 특성 파악.

 

private void textBox1_Validating(object sender, CancelEventArgs e)
{
if (textBox1.Text == null || textBox1.Text == "") return;

string szBuff = textBox1.Text;
foreach (char cData in szBuff)
{
// 문자가 있는경우 false
if (Char.IsNumber(cData) == false)
{
MessageBox.Show("문자가 포함되어있습니다. .. " + szBuff);
return;
}
}
}

 

FileStream과 StreamWriter/Reader를 사용하는데, 파일 공유 모드로 사용하고자 한다.

프로그램 구동중에 StreamWriter를 사용하고, File을 close하지 않고, 종료시점에 close 처리.

close 못하기에 file 공유모드로 open해서 Close되어있지않아도 StreamReader가 가능하다.

단 Close 시점에 파일이 Write되므로, StreamWriter의 Autoflush를 true로 설정해두자.

 

#region filestream 속성 사용 하여, Write/Read 공유 모드로 open하기 연습
// close 하지 않은 상태에서
FileStream file = new FileStream(@"c:\sample.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
private void write_Click(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(file);
sw.AutoFlush = true;
sw.WriteLine("write_Click(object sender, EventArgs e)");
// sw.Close();

}

private void read_Click(object sender, EventArgs e)
{
try
{
FileStream file = new FileStream(@"c:\sample.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(file);
string read = sr.ReadToEnd();
sr.Close();
file.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}

}

#endregion

 

간단하게 함수 수행시간을 측정하고 싶은경우..

 

long start = DateTime.Now.Ticks;
-------------------------------- 함수 수행.

long end = DateTime.Now.Ticks;


MessageBox.Show(string.Format("Thread time : {0}", (double)(end - start) / 10000000.0F));

 

끝.~~

 

File Stream으로 비동기 Writer를 해보면,

비동기 방식이 좋긴한데.. Write되는 문자열의 신뢰성이 부족하다.

 

예를들어 100번 loop를 돌면서 Log를 써야되는 경우가 발생한다면.

private void Begin_Writer(object sender, EventArgs e) // 비동기 Writer 할경우 time 측정
{
long start = DateTime.Now.Ticks;

for (int i = 0; i < 100; i++)
{
string sz = string.Format("BeginWrite : [2012-08-29 10:10:01.685] [2012-08-29 10:10:01.685][2012-08-29 10:10:01.685]{0} \r\n", i);
byte[] test = Encoding.UTF8.GetBytes(sz);
_write.BeginWrite(test, 0, sz.Length, wcallback, null);
Thread.Sleep(2); // 안정적 Writing에 필요한 time
}

long end = DateTime.Now.Ticks;

MessageBox.Show(string.Format("BeginWrite time : {0}", (double)(end - start) / 10000000.0F));

}

==> Time -> 0.1~ 0.2 정도

 

// WriterLine 함수를 사용한 예 ,, 별도의 Wait이 필요치 않다. Write자체가 동기적 수행됨.

private void StreamWriter의 WriterLine(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(_write);
sw.AutoFlush = true;

long start = DateTime.Now.Ticks;
for (int i = 0; i < 100; i++)
{
string sz = string.Format("WriteLine : [2012-08-29 10:10:01.685] [2012-08-29 10:10:01.685][2012-08-29 10:10:01.685]{0}", i);
sw.WriteLine(sz);
}

long end = DateTime.Now.Ticks;
MessageBox.Show(string.Format("WriteLine time : {0}", (double)(end - start) / 10000000.0F));
}

==> Time -> 0.001 ~ 0

 

// Threading 처리하여, Log 문자열을 Queue에 넣고, 다른 Thread에서 Queue가 있을경우 File Writing하는 방식.. -> 안정적 사용 --> 요것으로 선택.

private void button8_Click(object sender, EventArgs e)
{
swth.AutoFlush = true;
long start = DateTime.Now.Ticks;
for (int i = 0; i < 100; i++)
{
string sz = string.Format("WriteLine : [2012-08-29 10:10:01.685] [2012-08-29 10:10:01.685][2012-08-29 10:10:01.685]{0}", i);
ReqLog(sz);
}

long end = DateTime.Now.Ticks;
MessageBox.Show(string.Format("Thread time : {0}", (double)(end - start) / 10000000.0F));
}

==> Time -> 0.001 ~ 0

 

SYSTEM 에 의해서 파일이 잠기는 현상

제목에서 말하는 "SYSTEM"은 실행상태에서 파일을 잠그는 어떤 일반적인 프로세스를 가리키는 것이 아니고, 작업 관리자에서 보면 "System" 이라고 지칭되는 프로세스를 말합니다. 즉, 물리적인 EXE 파일도 가지고 있지 않은 그 "System" 프로세스입니다.

현상은, 빌드 서버에서 이뤄지는 컴파일이 계속 다음과 같이 실패하는 것으로 시작되었습니다.

CopyFilesToOutputDirectory:
Copying file from "obj\Release\Test.exe" to "D:\...\bin\Test.exe".
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2868,9):
error MSB3021: Unable to copy file "obj\Release\Test.exe" to "D:\...\bin\Test.exe". The process cannot access the file 'D:\...\bin\Test.exe' because it is being used by another process.
[D:\...\Test.csproj]
Done Building Project "D:\...\Test.csproj" (default targets) -- FAILED.



위의 경우에는 "Test.exe" 라는 파일명이었지만, 재미있게도 이 현상들은 모든 EXE 확장자를 가진 파일에 공통적으로 발생했습니다. 도대체 어떤 프로세스가 잠그고 있는지 확인하기 위해 "LockHunter"로 보니, 다음과 같이 "SYSTEM" 이었습니다. ^^;



세상에... "System"이라니... 절망적이라고 볼 수 있는 상황이었습니다. ^^;

그렇다고 해서 아주 잠겨진 것도 아닙니다. 그냥 탐색기에서 메뉴를 이용하여 삭제를 하면 그냥 지워집니다.

그런데, 명령행에서 이 작업을 하면 매우 재미있는 결과가 나옵니다. (다음은 3번 연속으로 삭제시도를 한 것입니다.)

D:\...\bin>del c:\temp\Test.exe     <--- 첫번째 시도

D:\...\bin>del c:\temp\Test.exe     <--- 두번째 시도
c:\temp\Test.exe
Access is denied.

D:\...\bin>del c:\temp\Test.exe     <--- 세번째 시도
Could Not Find c:\temp\Test.exe


^^; 바이러스일까???? 싶어서 백신으로 검사해보았으나 아무런 이상이 없었습니다. (물론, 해당 백신 프로그램이 100% 완벽하게 보장할 수는 없지만.)

또 하나 재미있는 현상은, 탐색기에서 보안 탭을 눌러보면 다음과 같이 설정을 (일반 사용자 권한으로는) 못한다고 나옵니다.



그래서, 부모 폴더로부터 보안을 상속받도록 하기 위해 직접 부모 폴더의 보안을 변경해서 적용하는데 다음과 같이 할 수 없다고 나옵니다.



더욱 재미있는 것은, 저런 식으로 속성창을 띄우거나 하면 해당 EXE 파일이 가끔씩 삭제된다는 것입니다.




오류 현상이 워낙 설명하기 힘들다 보니, 해결책을 위한 검색도 힘들었습니다. "SYSTEM" 이라는 단어와 "lock"이라는 단어를 조합하니 그다지 영양가있는 결과가 나오지 않았는데요. 다행히 다음과 같은 글을 발견할 수 있었습니다.

What part of Windows 7 randomly locks executable files?
; http://forums.somethingawful.com/showthread.php?threadid=3313767


해결책은?
"Application Experience" 서비스를 활성화시켜주면 됩니다. 그러고 보니 생각이 나버렸습니다. ^^; 최근 빌드 서버의 메모리 부족으로 어떻게든 가용 메모리를 확보하고자 몇몇 필요없을 것 같은 NT 서비스를 "Disabled" 상태로 바꿔버렸는데 바로 그것이 문제가 된 것입니다.

아무리 그렇다고는 해도... 정말이지 부작용 자체는 지나치게 유별난 것 같습니다. ^^;

하기 site에서 발췌했습니다.

감사합니다.

'프로그래밍 > .Net' 카테고리의 다른 글

Tick time 측정  (0) 2014.01.17
FileStream 비동기 file writer  (0) 2014.01.17
EventLog 활용하기  (0) 2014.01.17
FileStream 비동기 입출력  (0) 2014.01.17
XML 사용하여 특정 속성값 대체하기  (0) 2014.01.17

로그 기록을 함에있어,

상주 프로그램이 날짜별로 로그를 변경하고 싶다.

Write할때마다 비교하는것도 방법이겠지만..

날짜변경이 자주 발생하는건 아니니..

 

System의 EventLog를 활용해서, Event로 System날자변경이 있을경우,

Log 폴더명을 바꾸는 동작을 구성하였다.

 

// 하기 소스 참고.

public Form1()
{
InitializeComponent();

log.EntryWritten += new EntryWrittenEventHandler(log_EntryWritten);
log.EnableRaisingEvents = true; // Event log alarm 설정
}

private void button1_Click(object sender, EventArgs e)
{
log.EnableRaisingEvents = false; // event log를 알림 해제.
}

static void log_EntryWritten(object sender, EntryWrittenEventArgs e)
{
// Kernel-General
if (e.Entry.InstanceId == 1 && e.Entry.EntryType == EventLogEntryType.Information)
MessageBox.Show("e.Entry.InstanceId == 1 " + e.Entry.Message.ToString());

}

 

using System;
using System.Collections.Generic;
using System.Text;

using System.IO;
using System.Threading;

namespace ConsoleApplication2
{
class Program
{
static FileStream asyncfs =
new FileStream("ASyncTest.txt", FileMode.Open, FileAccess.Read, FileShare.None, 255, true);
static AsyncCallback callback = new AsyncCallback(CallBackFunction);
static byte[] readBuf = new byte[asyncfs.Length];

static void Main(string[] args)
{
asyncfs.BeginRead(readBuf, 0, readBuf.Length, callback, null);

for( int i=0; i<3; i++ )
{
Console.WriteLine("This is a Main() Loop Code - " + (i+1).ToString());
Thread.Sleep(1000);
}

asyncfs.Close();

}

static void CallBackFunction(IAsyncResult asyncResult)
{
int readB = asyncfs.EndRead(asyncResult);
if( readB > 0 )
{
asyncfs.Seek(0, SeekOrigin.Begin);
asyncfs.BeginRead(readBuf, 0, readBuf.Length, callback, null);
Console.WriteLine(Encoding.ASCII.GetString(readBuf, 0, readB));
Thread.Sleep(1000);
}
}
}
}

+ Recent posts