2013年8月17日 星期六

Parallel.Foreach取得目前元素之索引位置

想法:在影像處理run pixel上用了Parallel Foreach跟For,比非Parallel的快非常多,但是卻少了Index。在做pixel操作的時候有時需要知道要寫回哪裡。
實作:
            byte[] byteArray = binary.Bytes; //size:307200
            var query = byteArray.Select((val, idx) => new { Index = idx, Value = val });
            int[] result = new int[byteArray.Length];

            //平行 擇一上註解
            Parallel.ForEach(query, b=>
            {  
                if (b.Value >= 255)
                {
                    result[b.Index] = -1;
                }

            } //close lambda expression
                 ); //close method invocation

            //非平行 擇一上註解
            foreach (var b in query)
            {
                if (b.Value >= 255) result[b.Index] = -1;

            }



結論:驚!! Parallel方法花了25ms。非Parallel花了17ms。Parallel for是否又比Parallel foreach?!
             等國科會結束我再來比較一下Parallel for!!!

2013年8月16日 星期五

在WPF將RGB轉HSV調亮度後轉回RGB再SHOW圖 using Emgu CV

想法:因為系統需要由使用者動態調整亮度。
實作:
Code:
        private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {  //sourceBgr&sourceHsv 事先建立
            Image<Rgb, byte> rgb = sourceBgr.Clone();
            Image<Hsv, byte> Hsv = sourceHsv.Clone();
            CvInvoke.cvCvtColor(rgb, Hsv, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_RGB2HSV);     
            int  newValue=(int)e.NewValue; //取得slider事件發生後的值          
            string s = newValue.ToString();
            label1.Content = s;
            if (Hsv != null)
            {
                for (int j = 0; j < sourceHsv.Height; j++)
                {
                    for (int i = 0; i < sourceHsv.Width; i++)
                    {
                        byte value=0;
                        if (Hsv.Data[j, i, 2] + newValue > 255) value = 255;
                        else if (Hsv.Data[j, i, 2] + newValue < 0) value = 0;
                        else value = (byte)(Hsv.Data[j, i, 2] + newValue);

                        Hsv.Data[j, i, 2] = value;
                    }
                }
            }
            CvInvoke.cvCvtColor(Hsv, rgb, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_HSV2RGB);

            image1.Source = rgb.ToBitmapSource();
        }

紀錄:Hsv的v(value)是亮度,只要調整它即可調整該PIXEL的亮度。

在WPF做倒數計時器

想法:因為系統需要倒數計時器來執行拍照。
實作:

step 1: 加入System.Windows.Forms參考,並引入。
step 2: coding!
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            timer1 = new Timer();//global
            timer1.Interval = 1000;
            second = 5;//global
            timer1.Tick+=new EventHandler(timer1_Tick);
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (second > 0)
            {
                label1.Content = second ;
                second--;
            }
            else
            {
                timer1.Stop();
                label1.Content = "";
                BitmapImage bi = new BitmapImage(new Uri("/Image/p3.jpg", UriKind.RelativeOrAbsolute));
                image1.Source = bi;

            }

        }

Label用FontSize調字型大小。

2013年8月13日 星期二

EMGU CV的GPU測試運作

想法:目前系統用到emgu cv non-gpu的函式,是否改用gpu 函式效能就會提升?
實作:先run起emgu cv gpu的函式,以及針對靜態影像做簡易的影像處理。

Step1: GPU package
GPU for image processing is only available for Emgu CV rev 2.2.1 and later. Only package containing -gpu in its name (e.g. libemgucv-xxx-gpu-xxx) has GPU processing enabled.
  • Install the latest cuda graphic card driver from NVIDIA on your running platform.
  • Copy the cuda and npp dll files: cudart{bit}_{maj_rev}_{min_rev}.dll and npp{bit}_{maj_rev}_{min_rev}.dll to the execution directory
  • Add Emgu.CV.GPU.dll to References
  • Optionally put the following lines in the top of your code to include the Emgu.CV.GPU namespace.


Step2:
針對同一張800*533影像做灰階->FastCorner->轉bitmapsouce後用元件show圖,過程皆用Image類型運算。GPU cost time 是 82ms,non-gpu cost time是 17ms。


記錄:第一台ASUS BM6650 i5-2500 3.3GHz intel內顯 品牌電腦。執行時會有unknown error,初估是非nvidia的顯卡。第二台配備nvidia quadro工作站顯卡,成功執行。

結論:gpu函式再初始階段較耗時,在簡易的影像處理函式中無法展現高效能特性,或許在更高計算量的影像處理需要時,能展現其高效能之特性,像是KinectFusion(real-time 3D reconstruction)。

2012年5月5日 星期六

QRCode產生器與解碼器


    從井民全老師的blog中看到有寫到有關QRCode的操作後馬上著手練習,之後又在youtube看到一個作者用很簡潔的內容寫出了QRCode的操作,以下的是參考monsterhunter445後寫出的程式碼。與井民全老師的差別在於,monsterhunter445作者是載入了MessagingToolkit.QRCode.dll。
    原始碼分享在下面:

此程式可依輸入的網址來編成QRCode





















匯整數個例子在一個專案(轉黑白照、反轉顏色..等)

利用高效率的方法寫出「轉成黑白照」、「反轉顏色」、「紅色瀘鏡」、「綠色瀘鏡」、「藍色瀘鏡」、「增加亮度」。




2012年5月4日 星期五

紅綠藍瀘鏡運用&增加圖片亮度

紅綠藍瀘鏡運用與提高圖片亮度。

這一個程式bug找好久,因為我的邏輯跟作者寫的不同。最後我用自已的邏輯來使用function,才成功。

先說瀘鏡。與作者的code相比,我沒有setRGBData_unsafe( )與getRGBData_unsafe( ),我直接在ColorFilter功能裡完成了上述兩個功能的工作呼叫getRGBData( )與setRGBData( )來抓「三維陣列」與「由陣列建立新的 Bitmap」,然後更新掉image,就完成了。(另外,SHOW圖的方式也不同,作者用LoadImage( )影像公用程式,我寫不出來,所以用了另一個方法,這方法是在第一個範例裡學的。)(看紅字的code)


提高圖片的亮度與瀘鏡的計算類似,一樣一開始是做一個三維陣列,用三維陣列來跑每個pixel提高亮度,然後將三維陣列轉成Bitmap型態,再來把image更新掉,完成。


簡單的敘述執行順序:
點擊button->建立物件image->執行image.ColorFilter( )->用Bitmap把image包起來->
執行getRGBData( ),以取得存放pixel資訊的三維陣列->以此三維陣列執行瀘鏡的計算->
將三維陣列做成Bitmap型態的bimage->更新image->以視窗呈現處理後的圖片。