
How to go through each and every pixel of an image efficiently? 專案名稱: SpeedUpPixelAcessUnmaged code:第一種方式: MIplImage(1) MIplImage: managed structure equivalent to IplImage利用Marshal.PtrToStructure指向來源影像指標img.Ptr, 資料結構型態為 MIplImage, 記得前面強迫轉型(MIplImage)(2) IntPtr intPtr = mImg.ImageData;
C#利用IntPtr指標型態指向 ImageData: 存放影像像素資料起始位置
me1237guy 發表在 痞客邦 留言(2) 人氣(7,943)

最近在研究這篇Edge Based Template Matching, 以下為研究心得筆記原作者提供C++版本的實作(OpenCV 2.0 and Visual studio 2008 ), 搭配數學公式說明, 讓人很容易理解
這個方法(Feature based approach)相較於傳統(Gray value based approach)強健許多,
尤其當搜尋物件非完整顯示時,可以準確搜. 但計算量超大, 不適合大張圖像樣板比對
目前我已經成功改寫成C# Emgu CV版本, 之後考慮改以GPU版本加速, 以利實際應用
下面三張圖簡單說明本範例應用情形: 第一張圖(左下角)為template image(樣板影像)
me1237guy 發表在 痞客邦 留言(2) 人氣(9,173)

MATLAB: peaks指令VTK上視圖VTK 3Dzoom in參考資料:VTK/Examples/CSharp/Meshes/Color a mesh by height
me1237guy 發表在 痞客邦 留言(0) 人氣(55)
private Kitware.VTK.RenderWindowControl renderWindowControl1;
vtkAxesActor axes =
null;
List<vtkActor> vtkActors =
new List<vtkActor>();
public Form1()
{
InitializeComponent();
renderWindowControl1 =
new RenderWindowControl();
splitContainer1.Panel2.Controls.Add(renderWindowControl1);
renderWindowControl1.Show();
renderWindowControl1.Dock = DockStyle.Fill;
}
me1237guy 發表在 痞客邦 留言(0) 人氣(209)

加入參考Kitware.mummy.Runtime.dll和Kitware.VTK.dll
public partial class Form1 : Form
{
private Kitware.VTK.RenderWindowControl renderWindowControl1;
List<vtkActor> vtkActors =
new List<vtkActor>();
public Form1()
{
InitializeComponent();
renderWindowControl1 =
new RenderWindowControl();
splitContainer1.Panel2.Controls.Add(renderWindowControl1);
renderWindowControl1.Show();
renderWindowControl1.Dock = DockStyle.Fill;
}
me1237guy 發表在 痞客邦 留言(0) 人氣(88)

Add references: Kitware.mymmy.Runtime.dll and KitwareVTK.dll==============================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kitware.VTK;
namespace SimplePointsReader
{
public partial
class Form1 : Form
{
private Kitware.VTK.RenderWindowControl renderWindowControl1;
public Form1()
{
InitializeComponent();
renderWindowControl1 =
new RenderWindowControl();
this.Controls.Add(renderWindowControl1);
renderWindowControl1.Show();
renderWindowControl1.Dock = DockStyle.Fill;
}
me1237guy 發表在 痞客邦 留言(0) 人氣(195)

p0離紅色線段最近的點,即本身所在位置(1,0,0), 所以距離平方為0p1離紅色線段最近的點(1, 0, 0), 距離平方為4
// DistancePointToLine.cpp : 定義主控台應用程式的進入點。//#include "stdafx.h"#include <vtkSmartPointer.h>
#include <vtkLine.h>
#include <vtkPoints.h>
int _tmain(
int argc, _TCHAR* argv[])
{
double lineP0[3] = {0.0, 0.0, 0.0};
double lineP1[3] = {1.0, 0.0, 0.0};
double p0[3] = {1.0, 0, 0};
double p1[3] ={ 1.0, 2.0, 0};
/* vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New(); line->GetPoints()->SetPoint(0, lineP0); line->GetPoints()->SetPoint(0, lineP1); */{
double dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1);
std::cout <<
"Dist0: " << dist0 << std::endl;
double dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1);
std::cout <<
"Dist1: " << dist1 << std::endl;
}
{
double t;
double closest[3];
double dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1, t, closest);
std::cout <<
"Dist0: " << dist0 <<
" closest point: " << closest[0] <<
" " << closest[1] <<
" " << closest[2] << std::endl;
double dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1, t, closest);
std::cout <<
"Dist1: " << dist1 <<
" closest point: " << closest[0] <<
" " << closest[1] <<
" " << closest[2] << std::endl;
}
char c;
std::cin >> c;
return 0;
}
me1237guy 發表在 痞客邦 留言(0) 人氣(256)

同步兩個執行緒, 當Counter1++完成, 換Counter2++, 利用AutoResetEvent機制交換控制權由於同步的關係, 儘管兩組計數器跳動很快, 但下列條件成立 |Counter1 -Counter2| <= 1
public class Worker
{
int m_cnt1 = 0, m_cnt2 = 0;
Thread m_thread1;
Thread m_thread2;
TextBox m_textBox1, m_textBox2;
readonly AutoResetEvent m_syncEvent1 =
new AutoResetEvent(
false);
readonly AutoResetEvent m_syncEvent2 =
new AutoResetEvent(
true);
ManualResetEvent m_pauseEvent =
new ManualResetEvent(
true);
ManualResetEvent m_shutdownEvent =
new ManualResetEvent(
false);
void Job1()
{
while (
true)
{
m_pauseEvent.WaitOne(Timeout.Infinite);
if (m_shutdownEvent.WaitOne(0))
break;
m_syncEvent2.WaitOne();
m_cnt1++;
m_textBox1.BeginInvoke((MethodInvoker)
delegate {
m_textBox1.Text = m_cnt1.ToString();
});
Thread.Sleep(1);
m_syncEvent1.Set();
}
}
void Job2()
{
while (
true)
{
m_pauseEvent.WaitOne(Timeout.Infinite);
if (m_shutdownEvent.WaitOne(0))
break;
m_syncEvent1.WaitOne();
m_cnt2++;
m_textBox2.BeginInvoke((MethodInvoker)
delegate{
m_textBox2.Text = m_cnt2.ToString();
});
Thread.Sleep(1);
m_syncEvent2.Set();
}
}
public Worker() { }
public Worker(TextBox textBox1, TextBox textBox2)
{
m_textBox1 = textBox1;
m_textBox2 = textBox2;
}
public void Start()
{
m_thread1 =
new Thread(
new ThreadStart(Job1));
m_thread2 =
new Thread(
new ThreadStart(Job2));
m_thread1.Start();
m_thread2.Start();
}
public void Pause()
{
m_pauseEvent.Reset();
}
public void Resume()
{
m_pauseEvent.Set();
}
public void Stop()
{
m_shutdownEvent.Set();
m_pauseEvent.Set();
m_thread1.Join();
m_thread2.Join();
m_thread1 =
null;
m_thread2 =
null;
}
}
me1237guy 發表在 痞客邦 留言(0) 人氣(81)

Worker類別
public class Worker
{
/* Initializes a new intance of the ManualRestEvent class * with a Boolean value indicating whether to set the * initial state signaled */ private ManualResetEvent m_pauseEvent =
new ManualResetEvent(
true);
private ManualResetEvent m_shutdownEvent =
new ManualResetEvent(
false);
private Thread m_thread;
private int m_cnt = 0;
private string m_status;
private Label m_lbl;
private TextBox m_tBox;
private ProgressBar m_pBar;
public int UserID { get; set; }
public string Status
{
get {
return m_status; }
}
public int Count
{
get {
return m_cnt; }
set { m_cnt =
value; }
}
public Worker() { }
public Worker(Label lbl, TextBox tBox, ProgressBar pBar)
{
m_lbl = lbl;
m_tBox = tBox;
m_pBar = pBar;
}
#region Job
public void Job()
{
const int UPDATE_PERIOD = 10000;
while (
true)
{
/* 若收到訊號, 則m_pauseEvent程式繼續往下執行 * 反之, 沒有收到訊號, 則持續等待(infinite), * 程式不會往下執行(凍結) */ m_pauseEvent.WaitOne(Timeout.Infinite);
/* 若沒有收到訊號, 則一直等待訊號, * 但因為timeout設定等待 0 ms, 自動跳開回傳false * 反之, 收到訊號, 回傳true */ if(m_shutdownEvent.WaitOne(0))
break;
m_cnt++;
if (m_cnt % UPDATE_PERIOD == 0)
{
updateTextBox();
updateProgressBar();
}
}
}
#endregion#region Start
public void Start()
{
m_thread =
new Thread(Job);
m_thread.Start();
m_status =
"執行緒開始執行...";
updateLabel();
}
#endregion#region Pause
public void Pause()
{
// 將事件設定為未收到訊號, 會造成執行緒封鎖m_pauseEvent.Reset();
m_status =
"執行緒暫停";
updateLabel();
}
#endregion#region Resume
public void Resume()
{
// 將事件設定為收到訊號, 會封鎖的執行緒繼續m_pauseEvent.Set();
m_status =
"執行緒繼續";
updateLabel();
}
#endregion#region Stop
public void Stop()
{
/* m_shutdownEven事件收到訊號, * 則(m_shutdownEvent.WaitOne(0)) * 回傳true */ m_shutdownEvent.Set();
/* 記得通知_pauseEvent, 即_pauseEvent.Set(); * 否則通知_shutdownEvent也枉然 */ m_pauseEvent.Set();
/* 優雅地等執行緒結束, * 即 呼叫_thread.Join(); * 而不是Thread.Terminate */ m_thread.Join();
m_status =
"執行緒停止";
updateLabel();
}
#endregion#region Reset Cnt
public void ResetCnt()
{
m_cnt = 0;
}
#endregion#region Update UI
public void updateLabel()
{
if (m_lbl.InvokeRequired)
{
m_lbl.BeginInvoke((Action)(() => { updateLabel(); }));
}
else{
m_lbl.Text = m_status;
}
}
public void updateTextBox()
{
if (m_tBox.InvokeRequired)
{
m_tBox.BeginInvoke((Action)(() => { updateTextBox(); }));
}
else{
m_tBox.Text = m_cnt.ToString();
}
}
public void updateProgressBar()
{
if (m_pBar.InvokeRequired)
{
m_pBar.BeginInvoke((Action) (()=>{ updateProgressBar();}) );
}
else{
m_pBar.Value = m_cnt;
}
}
#endregion}
me1237guy 發表在 痞客邦 留言(0) 人氣(894)