Showing posts with label OpenCV. Show all posts
Showing posts with label OpenCV. Show all posts

Tuesday, January 28

Emgu.CV.CvInvoke invoke OpenCV function

cvInvoke simple tutorial

    เนื่องด้วยข้อเสียของ Emgu คือ เรื่องเอกสาร Tutorial หาอ่านยากมากๆ (ไม่นับรวม api class referrence) ในเว็บ wiki ของเขาเอง ก็ใช่ว่าจะมีตัวอย่างครบ นั่นอาจจะเป็นเพราะว่า Emgu เอง มันเองเป็น wrapper function ที่ครอบอยู่บน OpenCV อยู่ เลยทำให้ Developer เอง ไม่อยากจะทำ Tutorial ออกมา คงเข้าใจว่า ผู้นำ Emgu ไปใช้ คงมีความรู้พื้นฐานอยู่บ้าง และหากสงสัยใน Class ไหน ก็ให้หาอ่านเอาในเอกสารของ OpenCV หล่ะมั้ง (อันนี้ ผมคิดไปเองนะครับ)

ในเมื่อไม่มีทางเลือกที่จะต้องเรียกใช้ OpenCV Function ตรงๆ ใน .NET แล้ว ทาง Emgu ก็มี CvInvoke ที่จะทำให้เราสามารถเรียกใช้ OpenCV ได้โดยตรง และเมื่อเรียกใช้โดยตรงแล้ว ก็ให้อ้างอิงเอกสารของ OpenCV ได้เลย (ซึ่งมีตัวอย่างการใช้งาน และอื่นๆ ค่อนข้างครบ) เอาหล่ะ เรามาลองเขียน Emgu application โดยใช้ความสามารถของ CvInvoke กันดูครับ

สร้าง win application ขึ้นมา โดยทำตามขั้นตอนแรกๆ Getting started Emgu with Visual C# 2010 Express จากนั้นบนหน้าฟอร์มเปล่าๆ ก็สร้าง button ขึ้นมา 1 อัน แล้วก็เขียนไปบน Event double click ของมัน โดยดับเบิลคลิกที่ปุ่มบนฟอร์ม แล้วเขียนโค๊ดเหล่านี้ลงไป

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 Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;

namespace Emgu_cvInvoke
{
    public partial class Form1 : Form
    {
        MCvScalar color_text = new MCvScalar(255, 255, 255);
        MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5);
        IntPtr img = CvInvoke.cvCreateImage(new Size(200, 200), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CvInvoke.cvPutText(img, "Hello Emgu", new Point(50, 50), ref font, color_text);
            CvInvoke.cvShowImage("Simple Emgu application", img);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            CvInvoke.cvDestroyWindow("Simple Emgu application");
            CvInvoke.cvReleaseImage(ref img);
        }
    }
}

จริงๆ แล้ว ตัวอย่างนี้ เราใช้่ cvCreatImage (Creates an image header and allocates the image data ) เป็นแค่การจองหน่วยความจำสำหรับเก็บข้อมูลรูปภาพ แล้วก็ใส่ตัวอักษร ด้วย cvPutText ไปบนพื้นที่ว่างบนรูปภาพ (คือพื้นสีดำว่างๆ นั่นแหละ) โดยกำหนดตำแหน่งข้อความและขนาดและสีของตัวอักษรเท่านั้นเอง 

ซึ่งหากจะเปรียบเทียบรูปแบบฟังก์ชั่นของ cvCreatImage และ cvPutText กับ cvShowImage แล้วจะพบว่า รูปแบบของการใส่ Parameter เข้าไปในฟังก์ชั่นก็ยังเหมือนเดิมในเอกสารของ OpenCV ถึงแม้ว่าเรากำลังเขียนอยู่บน Emgu Framework ก็ตาม เพีิยงแค่เรียก cvInvoke แล้วก็ตามด้วยฟังก์ชั่นบน OpenCV จากนั้นก็เติมพารามิเตอร์ให้ครบตามเอกสาร เท่านี้ เราก็เรียกใช้ OpenCV function ได้แล้วครับ

Emgu.CV.CvInvoke invoke OpenCV function

cvCreateImage

cvPutText

cvShowImage

แล้วทดสอบรันโปรแกรมดูครับ

image

งาน Image Processing บางอย่างเราอาจจะเจอวิธีแก้ไข ด้วย OpenCV Function ซึ่งถ้าหากเราต้องการนำมาใส่ใน Emgu Application ของเรา ก็เพียงเรียกใช้ cvInvoke เข้ามา แล้วก็ปรับแก้นิดหน่อยให้เป็นไปตาม .NET syntax เราก็อาจจะจบงานของเราได้เหมือนกัน ลองเอาไปประยุกต์ดูครับ

แล้วสนุกกับ Emgu นะครับ

ปล. และหากต้องการนำข้อมูลรูปภาพที่อยู่ใน pointer img กลับไปใส่ใน picturebox control ก็สามารถทำได้ ด้วยการใช้ CvInvoke.cvCopy Method โดยปลายทางของข้อมูล อาจจะเป็น bitmap แต่ size และ channel ต้องเท่ากันกับภาพต้นฉบับ และใช้ pointer properties ของตัวแปรปลายทางด้วย

private void button1_Click(object sender, EventArgs e)
{
      Image<Gray, byte> img2 = new Image<Gray, byte>(200,200);
      CvInvoke.cvPutText(img, "Hello Emgu", new Point(50, 50), ref font, color_text);           
      CvInvoke.cvShowImage("Simple Emgu application", img);
      CvInvoke.cvCopy(img, img2.Ptr, IntPtr.Zero);
      pictureBox1.Image = img2.ToBitmap();
   
}

how to create bitmap from image pointer IplImage

how to create bitmap from image pointer IplImage

อ่านเพิ่มเติม...

Sunday, April 7

How to implement property sheet to other project in Visual C++

เราสามารถก๊อปปี้ค่าต่างๆ ใน Project Properities จากงานที่เราเคยกำหนดค่าไว้แล้ว มาใช้ใน Project ใหม่ได้ จะทำให้เราสามารถที่จะสร้างโปรเจคได้เลย โดยไม่ต้องไปกำหนดที่ Project Properties ทุกครั้งที่เราสร้างโปรเจคใหม่

เช่นงาน HelloOpenCV ที่เราได้กำหนด Project Properties path การเรียกใช้ library และการดึงไฟล์ dll เข้ามาร่วมในโปรเจคของเรา หากเรามีการสร้างไฟล์ Property sheet ไว้ก่อนแล้ว เราสามารถ add property sheet เข้ามาในโปรเจคใหม่ของเราได้เลย ซึ่งจะทำให้ path ต่างๆ ที่เคยกำหนดไว้ที่ C/C++ และ Linker ถูกกำหนดไว้อย่างเรียบร้อย ช่วยลดเวลาความยุ่งยากในการสร้างโปรเจคบน Visual C++ ได้เป็นอย่างดี เรามาดูกันครับว่าทำอย่างไร


ก่อนอื่น เราจะต้องสร้างไฟล์ properity sheet ขึ้นมาก่อน โดยจะอยู่ที่ tab property manager ซึ่งบางเครื่อง อาจจะยังไม่ปรากฏ tab นี้ ให้เราไปที่เมนู Tools->Settings->Expert Settings จะปรากฏ tab property manager ด้านล่าง

open tab property manager

 

Property manager tab bar

ในวีดีโอ ผมได้ทำการสร้างไฟล์ properity sheet โดยอาศัยจากโปรเจค HelloOpenCV ก่อน โดยให้เก็บไฟล์ OpenCVPropertiesDebug.props และไฟล์ OpenCVPropertiesRelease.props ไว้แยกต่างหาก จากโฟวเดอร์โปรเจคเรา จากนั้นกำหนดค่า ตามที่เราเคยได้กำหนดจากตัวอย่างก่อนหน้านี้  เรียบร้อยแล้วให้ทำการบันทึกไฟล์ทั้งสอง

ต่อจากนั้น เมื่อเราทำการ add new project เข้าไปใน  project solution ของเราให้ทำการไปเพิ่มไฟล์ property sheet เข้าไปที่ debug และ release ใน tab property manager ในโปรเจคที่เราสร้างใหม่

เมื่อเรามาทำการเขียนโค๊ด C++ ตอนที่เราสั่ง #include <cv.h> สังเกตได้ว่า Visual C++ IDE จะมองหา path ตามที่เราได้เพิ่มไฟล์ property sheet ตามที่เราได้กำหนดไว้ให้อัตโนมัติ

ง่ายไหมหล่ะครับ ทีนี้เวลาเราสร้างโปรเจคใหม่ขึ้นมา เราก็สามารถเพิ่มไฟล์ property sheet เข้าไป ทีเหลือ ก็ไม่ต้องไปกำหนดค่าอะไรให้วุ่นวายอีก จากนั้นก็บรรเลงเพลงโค๊ด C++ เราได้เลย

ขอให้สนุกกับ OpenCV นะครับ

อ่านเพิ่มเติม...

Thursday, March 28

How to implement system variables on Visual C++ Project

วันนี้ จะมาแนะนำการสร้างตัวแปร system variables เพื่อนำตัวแปรนี้ไปอ้างอิงในการกำหนดค่า path ใน Project ของ Visual C++ ครับ จากครั้งที่แล้ว เราได้สร้างโปรเจค HelloOpenCV กันไปแล้ว จะเห็นได้ว่า กว่าจะกำหนดค่าต่างๆ ให้กับโปรเจคนั้น ค่อนข้างมีรายละเอียดยุบยิบ เต็มไปหมด (นี่ยังไม่รวมถึงขั้นตอนเขียนโปรแกรมนะ) ทีนี้ เราจะมาลองใช้ลูกเล่น system variables ใน  Environment variables ใน windows กันดูครับ

เริ่มจากเปิด Environment variables ที่ system variables คลิกที่ New
จะมีหน้าต่าง dialog ขึ้นมา ให้เรากำหนดค่าดังนี้

Variable name : OPENCV_DIR
Variable value : E:\software\opencv

จุดประสงค์ก็คือ เราต้องการให้ตัวแปร OPENCV_DIR ซึ่งต่อไปเราจะเรียกใช้ด้วยการอ้างถึง $(OPENCV_DIR) มีค่าเท่ากับ E:\software\opencv ซึ่งเป็นการอ้างถึง directory path ที่อยู่ของไฟล์ต่างๆ ใน  E:\software\opencv นั่นเอง

กำหนดเสร็จแล้วให้กด OK แล้วก็รีสตาร์ทคอมพิวเตอร์ 1 ครั้ง

system variables

กลับมาที่โปรเจค HelloOpenCV ที่เราได้เคยสร้างไว้แล้ว ให้ทำการเปลี่ยนแปลงค่าต่างๆ ที่เราเคยกำหนดไว้ จากตอนที่แล้ว โดยให้เปลี่ยนแปลงตั้งแต่ E:\software\opencv ให้กลายเป็น $(OPENCV_DIR)

refer to system variables

เช่น ผมเคยกำหนดให้
จากเดิม E:\software\opencv\build\include\opencv
เปลี่ยนเป็น $(OPENCV_DIR)\build\include\opencv

เปลี่ยนให้หมดเลยนะครับ ทุกที่ ที่เราเคยกำหนด path มันไว้ เสร็จแล้วก็ลอง Build Solution ใหม่อีกครั้ง ซึ่้งก็ควรจะ build ผ่าน เหมือนที่มันเคย build ผ่านมาก่อน
หลายคนอาจจะสงสัยว่า ทำแบบนี้ มันดีอย่างไร นอกจากได้การได้การเรียก path ที่สั้นลง

อย่างแรกนะครับ ลองนึกดูเล่นๆ นะครับ หากผมกับเพือน ต้องการแชร์โปรเจคให้กันและกัน แต่บังเอิญว่าเพื่อนผม เค้าติดตั้ง OpenCV2.4 ไว้ที่ C:\Program Files (x86)\OpenCV2.4 แต่ผมติดตั้งไว้ที่  E:\software\opencv จะเกิดอะไรขึ้น หากผมนำโปรเจคของเพื่อนมารันที่เครื่องผม ถึงแม้เราจะใช้ Visual C++ เวอร์ชั่นเดียวกันก็ตาม ก็ต้องมานั่งแก้ค่าคอนฟิคต่างๆ ก่อนจะ build solution อย่างแน่นอน แต่ถ้าใช้วิธีนี้ เราสามารถนำโปรเจคคนอื่นมา build solution ใหม่ได้เลยทันที

อย่างที่สองก็คือ หากวันข้างหน้า  OpenCV ออกเวอร์ชั่นใหม่มา จากเดิมที่เราใช้อยู่ คือ OpenCV2.4 แล้วเปลี่ยนมาเป็นเวอร์ชั่น OpenCV2.5 หรือ OpenCV3.0 บางคนอาจจะเลือกที่จะแตกไฟล์ใหม่ทับของเก่า หรือไม่ก็ rename folder เอา แต่ ถ้าเรากำหนดค่าใน system variables ใน Environment variables ของ Windows แล้วหล่ะก็ เราก็แค่เปลี่ยนแปลงที่นี่ เท่านั้น จากเดิม

Variable name : OPENCV_DIR
Variable value : E:\software\opencv

ก็กำหนดใหม่เป็น

Variable name : OPENCV_DIR
Variable value : E:\software\OpenCV2.5\opencv

ที่เหลือในโปรเจค เราก็แค่ไปเปลี่ยน Linker>Input ให้ไปเรียกไฟล์ใหม่ อย่างน้อยเราก็ไม่ต้องตามไปแก้ไข config ใหม่ทั้งหมด  นี่ก็เป็นอีกเทคนิคหนึ่ง ที่ผมอยากจะนำเสนอครับ  ก็ลองเอาไปปรับๆ กันดูครับ หากใครมีเทคนิคใด น่าสนใจ ก็แชร์กันได้ครับ

อ่านเพิ่มเติม...

Wednesday, March 27

How to config OpenCV2.4 with VC++ 2010 Express

    ก่อนเราจะมาติดตั้ง OpenCV2.4 กับ Visual C++ 2010 Express เรามาทำความเข้าใจกับ OpenCV สักนิดครับ สั้นๆ เลยก็คือ

OpenCv คือ ไลบรารีที่เปิดให้ใช้เสรี สำหรับงาน Computer Vision ซึ่งได้รับการพัฒนามาอย่างต่อเนื่อง ทำให้มีอัลกอริธึมสำหรับแก้ไขปัญหา Computer Vision มากกว่า 2500 อัลกอริธึม และตัวอย่างโค๊ดสำหรับ computer vision แบบงานเรียลไทม์ ทำงานได้ทั้ง Windows ,Linux, Mac OS X, Android และ iOS

ณ ปัจจุบัน เท่าที่ผมทราบตอนนี้ รองรับทั้งภาษา C++ และ Python ครับ หากใครสาวกไพธอน สามารถติดตั้งได้ตามตัวอย่างนี้ครับ (ติดตั้งสำหรับ Python)


วันนี้เราจะมาติดตั้ง OpenCV2.4 กับ Visual C++ 2010 Express ซึ่งก่อนหน้านี้ ผมเคยติดตั้งไปแล้ว บน Windows XP ครับ แต่ไม่ได้เขียนเอาไว้ ตอนนี้ พออัพเกรดเครื่องมาเป็น Windows7 กลับพบว่า Visual C++ 2010 Express กลับมีความแตกต่างไปจากเดิม คือไม่มีการตั้งค่า VC++ Directories ครับ  ถ้าเราเลือกเมนู Tool->Options ที่ Projects and Solutions และรายการย่อย VC++ Directories จะปรากฏข้อความ VC++ Directories edition in Tools>Options has been deprecated ไปเรียบร้อยแล้ว ดังรูป

OpenCV and VC++ Directories issue

หากต้องการกำหนดค่าต่างๆ ให้โปรเจค VC++ ของเราให้เรียกไลบรารี่ของ OpenCV ให้มาทำงานแล้วหล่ะก็ ให้ทำดังต่อไปนี้ครับ

ซอร์ฟแวร์ที่จะทดสอบ OpenCV2.4 ก็มีดังต่อไปนี้ครับ
- ระบบปฏิบัติการ Windows7
- ไลบรารี่ OpenCV2.4.2 บน windows
- โปรแกรม Visual C++ 2010 Express edition

ทำการดาวน์โหลด OpenCV2.4 และแตกไฟล์ OpenCV ไปไว้ที่ใดๆ ก็ได้บนฮาร์ดดิสก์ของเรา ในที่นี้ผมไว้ที่ Drive E:\software\opencv

ติดตั้ง Visual C++ 2010 Express edition หากคุณยังไม่มี 

เมื่อติดตั้งเรียบร้อยแล้ว ให้ทำการกำหนด Path สำหรับ windows ให้มองเห็น OpenCV ก่อน โดยกำหนด Path ใน  Environment Variables โดยให้เราไปก๊อปปี้ path ของ OpenCV ดังนี้

E:\software\opencv\build\x86\vc10\bin
E:\software\opencv\build\common\tbb\ia32\vc10
 
ไปใส่ต่อจาก path เดิมที่มีอยู่ หากตัวสุดท้ายไม่มีเครื่องหมาย ; ให้เราทำการเติมเครื่องหมาย ; ก่อน แล้วจึงนำ path ทั้งสองไปต่อ จะได้ว่า

......พาธเก่า\bin;E:\software\opencv\build\x86\vc10\bin;E:\software\opencv\build\common\tbb\ia32\vc10;

เสร็จแล้ว กด OK ด้วยนะอย่าลืม แล้วทำการรีสตาร์ทคอมพิวเตอร์ 1 ครั้้ง

Environment Variables OpenCV path

กลับมาตั้งค่ากันต่อ ให้เปิดโปรแกรม Visual C++ 2010 Express แล้วทำการสร้างโปรเจค HelloOpenCV ขึ้นมาครับ ตามรูปเลย

Starting Project OpenCV

 

Starting Project OpenCV

 

OpenCV Project Properties

ที่เมนู C/C++ ให้คลิก Edit ที่  Additional Include Directories แล้วทำการ  Browse ไปหาพาธตามนี้ครับ

E:\software\opencv\build\include\opencv
E:\software\opencv\build\include

กด OK

OpenCV Include path config

และที่ Linker>General ให้คลิก Edit ที่    Additional Library Directories แล้วทำการ  Browse ไปหาพาธตามนี้ครับ

E:\software\opencv\build\x86\vc10\lib

กด OK

OpenCV Linker path setting

และที่ Linker>Input ให้คลิก Edit ที่  Additional Dependencies แล้วเพิ่มไฟล์เหล่านี้ลงไป หรือจะก๊อปปี้ไปก็ได้ครับ แต่ต้องแน่ใจนะว่า เวอร์ชั่นที่เรากำลังกำหนดอยู่นี้ ชื่อไฟล์ตรงกัน หากไม่ตรงกัน ให้แก้ไขก่อน

แต่ไฟล์ lib ที่เราจะเพิ่มเข้าไป นั้นมี 2 ชุดนะครับ ซึ่งไฟล์ที่ลงท้ายด้วยตัว ‘d’ นั้นสำหรับ Configuration แบบ Debug และ ที่ไม่มี 'd’ ต่อท้าย สำหรับ Configuration แบบ Release เราต้องทำแยกกันนะครับ

Cofiguration mode

OpenCV lib file input setting

สำหรับ Debug

opencv_core242d.lib
opencv_imgproc242d.lib
opencv_highgui242d.lib
opencv_ml242d.lib
opencv_video242d.lib
opencv_features2d242d.lib
opencv_calib3d242d.lib
opencv_objdetect242d.lib
opencv_contrib242d.lib
opencv_legacy242d.lib
opencv_flann242d.lib

สำหรับ Release

opencv_core242.lib
opencv_imgproc242.lib
opencv_highgui242.lib
opencv_ml242.lib
opencv_video242.lib
opencv_features2d242.lib
opencv_calib3d242.lib
opencv_objdetect242.lib
opencv_contrib242.lib
opencv_legacy242.lib
opencv_flann242.lib

กด OK แล้วก็ Apply แล้วก็ OK อีกครั้งครับ

จากนั้น ให้ทำการแก้ไขโค๊ดที่ไฟล์ HelloOpenCV.cpp ดังนี้

#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>


int _tmain(int argc, _TCHAR* argv[])

    const char *windowName = "my cats";
    IplImage *img = cvLoadImage("E:\\cat.png"); // อย่าลืมเอารูปไปวางไว้ที่นี่ด้วย
    cvNamedWindow(windowName,1);
    cvShowImage(windowName,img);

    cvWaitKey(0);
    cvDestroyWindow(windowName);
    cvReleaseImage(&img);
    return 0;

}

หากสังเกตให้ดี ตอนที่เรา #include <cv.h> จะมีตัวช่วยขึ้นมา นั่นบ่งบอกว่าโปรแกรม VC++ มองเห็นพาธที่เรากำหนดไว้แล้ว ทำการ
build Solution หรือกด F7 เมื่อเขียนโปรแกรมตัวอย่างเสร็จ  หากไม่มีอะไรผิดพลาด ควรจะได้ข้อความ

"========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped =========="

แล้วกด F5 หรือ Start Debugging จากเมนู Debug รูป cat.png ก็จะปรากฏบนหน้าต่าง my cats ของเราครับ

HelloOpenCV

ศึกษาเอกสารเพิ่มเติมจาก http://opencv.org/

ขอบคุณที่มา Jebson’s blog สำหรับการติดตั้งบน VC++ 2010

ขอให้สนุกกับ OpenCV นะครับ

อ่านเพิ่มเติม...
 

แจกฟรี พื้นที่ฝากไฟล์ 2 GB

ads

ติดตามข่าวสารผ่าน Twitter

ติดตาม Blog นี้

Blog อื่นๆของฉัน

จำนวนการเยี่ยมชมบล๊อก