画像処理

GR-KAEDEのカメラ用オプションボードを接続し、CMOSカメラOV7740から画像を取得、JPEGファイルの生成や、人物検知、動体検知を行うライブラリです。 使用する場合は、#include <image.h>を記述してください。

Image()

概要
画像処理ライブラリ用のコンストラクターです。
文法
Image image
パラメータ
なし
戻り値
なし

begin

概要
カメラモジュールの初期化やSDRAMの初期化を行います。
文法
image.begin()
パラメータ
なし
戻り値
なし
補足
複数のインスタンスを生成した場合でも、1度呼ぶだけでOKです。

captureStart

概要
写真を撮ります。カメラからのキャプチャーが終了したかisCaptureFinishedで確認してください。
文法
image.captureStart()
パラメータ
なし
戻り値
なし

isCaptureFinished

概要
カメラからのキャプチャーが終了したかを返します。
文法
image.isCaptureFinished()
パラメータ
なし
戻り値
true: キャプチャーが終了している。false: キャプチャー中。

createRgb565

概要
キャプチャーした画像から320x240サイズRGB565形式のデータを生成します。
文法
uint8_t* image.createRgb565()
パラメータ
なし
戻り値
データの格納ポインタ

createGrayImage

概要
320x240サイズRGB565形式のデータからグレー画像を生成します。グレー画像は人物検知、動体検知に必要になります。
文法
uint8_t* image.createGrayImage()
パラメータ
なし
戻り値
データの格納ポインタ

createJpg

概要
320x240サイズRGB565形式のデータからJPEG形式に圧縮してファイル生成します。
文法
uint8_t* image.createJpg()
パラメータ
なし
戻り値
データの格納ポインタ

getCreatedRgb565

概要
生成したRGB565形式のデータ格納先を取得します。
文法
uint8_t* image.getCreatedRgb565()
パラメータ
なし
戻り値
データの格納ポインタ

getCreatedGrayImage

概要
生成したグレー画像のデータ格納先を取得します。
文法
uint8_t* image.getCreatedGrayImage()
パラメータ
なし
戻り値
データの格納ポインタ

getCreatedJpg

概要
生成したJPEG画像のデータ格納先を取得します。
文法
uint8_t* image.getCreatedJpg()
パラメータ
なし
戻り値
データの格納ポインタ

getCreatedJpgSize

概要
生成したJPEG画像のサイズを取得します。
文法
int32_t image.getCreatedJpgSize()
パラメータ
なし
戻り値
データのサイズ

personDetection

概要
人物検知用の処理を行います。あらかじめグレー画像を生成する必要があります。
文法
bool image.personDetection()
パラメータ
なし
戻り値
true: 成功、false: 失敗
補足
本処理を行うと、RGB565の画像に検出結果が反映されます。

getPersonNumber

概要
personDetectionの結果として、エリア内に検知した人物数を返します。
文法
bool image.getPersonNumber(area)
パラメータ
area: 以下に示す1~9のエリア。0を指定した場合、全てのエリア(デフォルト)。
1 2 3
4 5 6
7 8 9
戻り値
指定エリア内の人数
補足
1エリア内の最大検知人数は5人です。検知の距離は4メートルで最適化されています。

movingDetection

概要
動体検知用の処理を行います。あらかじめグレー画像3枚を生成する必要があります。
文法
bool image.movingDetection(uint8_t* before_gray_image1, uint8_t* before_gray_image2)
パラメータ
before_gray_image1: 2回前のグレー画像。
before_gray_image2: 1回前のグレー画像。
戻り値
true: 成功、false: 失敗
補足
本処理を行うと動体検知の結果がRGB565の画像に反映されます。

getMovingNumber

概要
movingDetectionの結果として、検知した動体物数を返します。
文法
bool image.getMovingNumber()
パラメータ
なし
戻り値
動体の物体数

getMovingArea

概要
movingDetectionの結果として、動体物の検知エリアを返します。
文法
bool image.getMovingArea(moving)
パラメータ
moving: 動体の番号を指定します。0は一番大きな動きがあった物体です。以降大きい順の番号になります。
戻り値
以下に示す検知エリア
1 2 3
4 5 6
7 8 9

サンプルプログラム

動体検知をしてSDカードにどんどん保存するサンプルです。


/*
 This sample enables to take a photo that include moving detection. 
 After taking a photo, the photo will be compressed to JPEG file and 
 then saved to SD card. 
 Hardware: GR-KAEDE, camera option and SD. Also USB cable and PC.
 note: This sample needs to install USB driver for GR-KAEDE
       The USB driver is in the project folder just you created.
       Also you need to install a terminal software like Teraterm.
*/ 

#include <Arduino.h>
#include "Image.h"
#include "SD.h"
#include "RTC.h"

Image image[3];
RTC_TIMETYPE t;
void dateTime(uint16_t* date, uint16_t* time);

void setup(){
    Serial.begin(9600);
    while(!Serial.available()); // wait to press key
    Serial.read(); //dummy
    Serial.println("start");

    if(!SD.begin()){
        Serial.println("Failed to access SD.");
    } else {
        Serial.println("Success to access SD.");
    }

	// RTC for time stamp in SD
    rtc_init();
    t.year = 15;
    t.mon = 9;
    t.day = 2;
    t.weekday = RTC_WEEK_WEDNESDAY;
    t.hour = 17;
    t.min = 0;
    t.second = 0;
    rtc_set_time(&t);

    SdFile::dateTimeCallback( &dateTime );

	// Initialize Image library
    image[0].begin();

}

void loop(){

    static int cnt = 0;

	while(cnt < 2){ //necessary at least two image in the past.
        image[cnt].captureStart();
        while(!image[cnt].isCaptureFinished());
        image[cnt].createGrayImage();
        cnt++;
	}
	
    Serial.println("Capturing image");
    image[cnt%3].captureStart();
    while(!image[cnt%3].isCaptureFinished());
    image[cnt%3].createGrayImage();
	
	// Moving detection
    if( 0 == image[cnt%3].movingDetection(image[(cnt-2)%3].getCreatedGrayImage(), image[(cnt-1)%3].getCreatedGrayImage())){
        Serial.println("finish detection");
        Serial.print("Moving Number is:");
        Serial.println(image[cnt%3].getMovingNumber());
        Serial.print("The biggest moving is in area:");
        Serial.println(image[cnt%3].getMovingArea(0));
    }
    image[cnt%3].createJpg();

    Serial.println("Write jpg to SD:");

    char fn[20];
    sprintf (fn, "test%d.jpg", (cnt-2));
    File file = SD.open(fn, FILE_WRITE);
    uint8_t* adr = image[cnt%3].getCreatedJpg();
    int32_t size = image[cnt%3].getCreatedJpgSize();
    for (int i = 0; i < size; i++){
        file.write(*adr);
        adr++;
    }
    file.close();
    Serial.println("Done.");
	cnt++;
}

void dateTime(uint16_t* date, uint16_t* time)
{
  rtc_get_time(&t);

  *date = FAT_DATE(t.year+2000, t.mon, t.day);
  *time = FAT_TIME(t.hour, t.min, t.second);
}