This is a drawing theme game that uses a camera to draw

概要

Troubleshooting!

https://os.mbed.com/users/knzw/code/camera_oekaki/
このプログラムはOpenCVを使用するためCLI環境でコンパイルしてください。

これはカメラを使って絵を描くお絵描きお題当てゲームです。描き手と回答者の二人で遊べます。起動するとお題が出題されるので、描き手はそのお題を見てお題に合う絵をカメラを動かすことで一筆書きをしてください。回答者は描き手の描いた絵を見て、元のお題を当ててください。

遊び方

プログラム起動時、画面の右下に白文字のお題が出力されます。ディスプレイにはカメラの動きに合わせて線が出現します。初期状態では何も出力されないので、描き始めるときはユーザ・スイッチ0を押下してください。

納得の絵ができるか、後戻りができなくなったらユーザ・スイッチ0を押下してください。お題が消え、新しい線を書けなくなり、回答フェーズに移ります。
もしユーザ・スイッチ0を間違って押下した際は、もう一度ユーザ・スイッチ0を押下してください。お題が出現し、続きから再開することができます。

消しゴム機能
ユーザ・スイッチ1を押下すると消しゴムになり、描いた線を消せるようになります。描画したものを消したいときはユーザ・スイッチ1を押下してください。もう一度ユーザ・スイッチ1を押下すると線を書けるようになります。

使用機器

このプログラムは次の機器を使用します。

  • GR-LYCHEE            
  • TFT液晶モジュール     
  • カメラモジュール

お題の追加・変更

次のoekaki_theme.cppの中にある配列themeに要素を追加することでお題を増やすことができます。

oekaki_theme.cpp

char *theme[]={
  "STAR",
  "HEART",
  "HOUSE",
  "TIE",
  "BOOK",
  "PEN",
  "TREE",
  "CANDLE",
  "THUNDER",
  "COFFEE CUP"
};


要素の追加方法
追加したいお題をダブルクォーテーション(")で囲み、最後にカンマ(,)をつけてたものを、「char *theme[]={」の次の行に追加してください。

例:お題"DOG"を追加したい場合
「"DOG",」という文字列を、「char *theme[]={」の次の行に追加してください。
追加例

oekaki_theme.cpp

char *theme[]={
  "DOG",    /* ここに追加した */
  "STAR",
  "HEART",
  "HOUSE",
  "TIE",
  "BOOK",
  "PEN",
  "TREE",
  "CANDLE",
  "THUNDER",
  "COFFEE CUP"
};

構成

GR-LYCHEEで使う想定でプログラムを書いています。
USBコネクタに関してはMicroUSBコネクタ, MicroUSBコネクタのどちらに接続しても動作します。

Committer:
knzw
Date:
Fri Sep 06 03:03:47 2019 +0000
Revision:
0:a5b12f5693c6
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
knzw 0:a5b12f5693c6 1 #include "mbed.h"
knzw 0:a5b12f5693c6 2 #include "opencv.hpp"
knzw 0:a5b12f5693c6 3 #include "EasyAttach_CameraAndLCD.h"
knzw 0:a5b12f5693c6 4 #include "dcache-control.h"
knzw 0:a5b12f5693c6 5 #include "AsciiFont.h"
knzw 0:a5b12f5693c6 6 #include "hal/trng_api.h"
knzw 0:a5b12f5693c6 7 #include "oekaki_theme.h"
knzw 0:a5b12f5693c6 8
knzw 0:a5b12f5693c6 9
knzw 0:a5b12f5693c6 10 #define PLOT_INTERVAL (30)
knzw 0:a5b12f5693c6 11 #define DIST_SCALE_FACTOR_X (6.0)
knzw 0:a5b12f5693c6 12 #define DIST_SCALE_FACTOR_Y (6.0)
knzw 0:a5b12f5693c6 13
knzw 0:a5b12f5693c6 14 #define STRING_DISP_TEST (1)
knzw 0:a5b12f5693c6 15 #define DRAW_POINT (3)
knzw 0:a5b12f5693c6 16 #define ERASER_POINT (8)
knzw 0:a5b12f5693c6 17 #define TOUCH_BUFFER_BYTE_PER_PIXEL (2u)
knzw 0:a5b12f5693c6 18 #define TOUCH_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
knzw 0:a5b12f5693c6 19 #define COLOR_BLUE cv::Scalar(0,255,0)
knzw 0:a5b12f5693c6 20
knzw 0:a5b12f5693c6 21
knzw 0:a5b12f5693c6 22 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
knzw 0:a5b12f5693c6 23 in accordance with the frame buffer burst transfer mode. */
knzw 0:a5b12f5693c6 24 #define VIDEO_PIXEL_HW (160u) /* HQVGA */
knzw 0:a5b12f5693c6 25 #define VIDEO_PIXEL_VW (120u) /* HQVGA */
knzw 0:a5b12f5693c6 26
knzw 0:a5b12f5693c6 27 #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u)
knzw 0:a5b12f5693c6 28 #define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW)
knzw 0:a5b12f5693c6 29
knzw 0:a5b12f5693c6 30 #if defined(__ICCARM__)
knzw 0:a5b12f5693c6 31 #pragma data_alignment=32
knzw 0:a5b12f5693c6 32 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram";
knzw 0:a5b12f5693c6 33 static uint8_t user_frame_buffer1[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]@ ".mirrorram";
knzw 0:a5b12f5693c6 34 #else
knzw 0:a5b12f5693c6 35 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
knzw 0:a5b12f5693c6 36 static uint8_t user_frame_buffer1[TOUCH_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));//cameraみたい
knzw 0:a5b12f5693c6 37 #endif
knzw 0:a5b12f5693c6 38 static volatile int Vfield_Int_Cnt = 0;
knzw 0:a5b12f5693c6 39
knzw 0:a5b12f5693c6 40 static InterruptIn skip_btn0(USER_BUTTON0);
knzw 0:a5b12f5693c6 41 static InterruptIn skip_btn1(USER_BUTTON1);
knzw 0:a5b12f5693c6 42 static int sta=0;//描画のon,off switch
knzw 0:a5b12f5693c6 43 static int clr=0;//カラー選択(0=青、 1=黒(消しゴム))
knzw 0:a5b12f5693c6 44 static int layer2flg=0;
knzw 0:a5b12f5693c6 45 static int firstflg=0;
knzw 0:a5b12f5693c6 46 static int kesiflg=0;//1のとき、消しゴムを使ったあと。
knzw 0:a5b12f5693c6 47 static int16_t RangeCorr(int16_t target ,int16_t uplimit,int16_t lowlimit);
knzw 0:a5b12f5693c6 48 static uint8_t get_random(void);
knzw 0:a5b12f5693c6 49
knzw 0:a5b12f5693c6 50 DisplayBase Display;
knzw 0:a5b12f5693c6 51 DigitalOut led1(LED1);
knzw 0:a5b12f5693c6 52 static Thread mainTask(osPriorityNormal, 1024 * 16);
knzw 0:a5b12f5693c6 53
knzw 0:a5b12f5693c6 54 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
knzw 0:a5b12f5693c6 55 if (Vfield_Int_Cnt > 0) {
knzw 0:a5b12f5693c6 56 Vfield_Int_Cnt--;
knzw 0:a5b12f5693c6 57 }
knzw 0:a5b12f5693c6 58 }
knzw 0:a5b12f5693c6 59
knzw 0:a5b12f5693c6 60 static void wait_new_image(void) {
knzw 0:a5b12f5693c6 61 Vfield_Int_Cnt = 1;
knzw 0:a5b12f5693c6 62 while (Vfield_Int_Cnt > 0) {
knzw 0:a5b12f5693c6 63 ThisThread::sleep_for(1);
knzw 0:a5b12f5693c6 64 }
knzw 0:a5b12f5693c6 65 }
knzw 0:a5b12f5693c6 66
knzw 0:a5b12f5693c6 67
knzw 0:a5b12f5693c6 68 static void Start_Video_Camera(void) {
knzw 0:a5b12f5693c6 69 // Field end signal for recording function in scaler 0
knzw 0:a5b12f5693c6 70 Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield);
knzw 0:a5b12f5693c6 71
knzw 0:a5b12f5693c6 72 // Video capture setting (progressive form fixed)
knzw 0:a5b12f5693c6 73 Display.Video_Write_Setting(
knzw 0:a5b12f5693c6 74 DisplayBase::VIDEO_INPUT_CHANNEL_0,
knzw 0:a5b12f5693c6 75 DisplayBase::COL_SYS_NTSC_358,
knzw 0:a5b12f5693c6 76 (void *)user_frame_buffer0,
knzw 0:a5b12f5693c6 77 FRAME_BUFFER_STRIDE,
knzw 0:a5b12f5693c6 78 DisplayBase::VIDEO_FORMAT_YCBCR422,
knzw 0:a5b12f5693c6 79 DisplayBase::WR_RD_WRSWA_32_16BIT,
knzw 0:a5b12f5693c6 80 VIDEO_PIXEL_VW,
knzw 0:a5b12f5693c6 81 VIDEO_PIXEL_HW
knzw 0:a5b12f5693c6 82 );
knzw 0:a5b12f5693c6 83 EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0);
knzw 0:a5b12f5693c6 84 }
knzw 0:a5b12f5693c6 85
knzw 0:a5b12f5693c6 86 #if MBED_CONF_APP_LCD
knzw 0:a5b12f5693c6 87 static void Start_LCD_Display(void) {
knzw 0:a5b12f5693c6 88 DisplayBase::rect_t rect;
knzw 0:a5b12f5693c6 89
knzw 0:a5b12f5693c6 90 /* The layer by which the touch panel location is drawn */
knzw 0:a5b12f5693c6 91 memset(user_frame_buffer1, 0, sizeof(user_frame_buffer1));//framebufferの名前を変えた、
knzw 0:a5b12f5693c6 92 dcache_clean(user_frame_buffer1, sizeof(user_frame_buffer1));//framebufferの名前を変えた、
knzw 0:a5b12f5693c6 93 rect.vs = 0;
knzw 0:a5b12f5693c6 94 rect.vw = LCD_PIXEL_HEIGHT;
knzw 0:a5b12f5693c6 95 rect.hs = 0;
knzw 0:a5b12f5693c6 96 rect.hw = LCD_PIXEL_WIDTH;
knzw 0:a5b12f5693c6 97 Display.Graphics_Read_Setting(
knzw 0:a5b12f5693c6 98 DisplayBase::GRAPHICS_LAYER_0,
knzw 0:a5b12f5693c6 99 (void *)user_frame_buffer1,
knzw 0:a5b12f5693c6 100 TOUCH_BUFFER_STRIDE,
knzw 0:a5b12f5693c6 101 DisplayBase::GRAPHICS_FORMAT_ARGB4444,
knzw 0:a5b12f5693c6 102 DisplayBase::WR_RD_WRSWA_32_16BIT,
knzw 0:a5b12f5693c6 103 &rect
knzw 0:a5b12f5693c6 104 );
knzw 0:a5b12f5693c6 105 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
knzw 0:a5b12f5693c6 106
knzw 0:a5b12f5693c6 107 ThisThread::sleep_for(50);
knzw 0:a5b12f5693c6 108 EasyAttach_LcdBacklight(true);
knzw 0:a5b12f5693c6 109 }
knzw 0:a5b12f5693c6 110
knzw 0:a5b12f5693c6 111 #if STRING_DISP_TEST
knzw 0:a5b12f5693c6 112 //文字列出力
knzw 0:a5b12f5693c6 113 #define STRING_PIXEL_HW (129)
knzw 0:a5b12f5693c6 114 #define STRING_PIXEL_VM (24)
knzw 0:a5b12f5693c6 115 #define STRING_BUFFER_BYTE_PER_PIXEL (2u)
knzw 0:a5b12f5693c6 116 #define STRING_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * STRING_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
knzw 0:a5b12f5693c6 117
knzw 0:a5b12f5693c6 118 #if defined(__ICCARM__)
knzw 0:a5b12f5693c6 119 #pragma data_alignment=32
knzw 0:a5b12f5693c6 120 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM];
knzw 0:a5b12f5693c6 121 #else
knzw 0:a5b12f5693c6 122 static uint8_t user_frame_buffer_string[STRING_BUFFER_STRIDE * STRING_PIXEL_VM]__attribute((aligned(32)));
knzw 0:a5b12f5693c6 123 #endif
knzw 0:a5b12f5693c6 124
knzw 0:a5b12f5693c6 125 static void string_task(void){
knzw 0:a5b12f5693c6 126 DisplayBase::rect_t rect;
knzw 0:a5b12f5693c6 127
knzw 0:a5b12f5693c6 128 memset(user_frame_buffer_string,0,sizeof(user_frame_buffer_string));
knzw 0:a5b12f5693c6 129 dcache_clean(user_frame_buffer_string,sizeof(user_frame_buffer_string));
knzw 0:a5b12f5693c6 130
knzw 0:a5b12f5693c6 131 rect.vs = LCD_PIXEL_HEIGHT - STRING_PIXEL_VM - 10;
knzw 0:a5b12f5693c6 132 rect.vw = STRING_PIXEL_VM;
knzw 0:a5b12f5693c6 133 rect.hs = LCD_PIXEL_WIDTH - STRING_PIXEL_HW-10;
knzw 0:a5b12f5693c6 134 rect.hw = STRING_PIXEL_HW;
knzw 0:a5b12f5693c6 135 Display.Graphics_Read_Setting(
knzw 0:a5b12f5693c6 136 DisplayBase::GRAPHICS_LAYER_2,
knzw 0:a5b12f5693c6 137 (void *)user_frame_buffer_string,
knzw 0:a5b12f5693c6 138 STRING_BUFFER_STRIDE,
knzw 0:a5b12f5693c6 139 DisplayBase::GRAPHICS_FORMAT_ARGB4444,
knzw 0:a5b12f5693c6 140 DisplayBase::WR_RD_WRSWA_32_16BIT,
knzw 0:a5b12f5693c6 141 &rect
knzw 0:a5b12f5693c6 142 );
knzw 0:a5b12f5693c6 143 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2);
knzw 0:a5b12f5693c6 144
knzw 0:a5b12f5693c6 145 AsciiFont ascii_font(user_frame_buffer_string,STRING_PIXEL_HW,STRING_PIXEL_VM,
knzw 0:a5b12f5693c6 146 STRING_BUFFER_STRIDE,STRING_BUFFER_BYTE_PER_PIXEL);
knzw 0:a5b12f5693c6 147
knzw 0:a5b12f5693c6 148 //(文字列, x, y, colour,font_size)
knzw 0:a5b12f5693c6 149 int num=get_random();
knzw 0:a5b12f5693c6 150 int layer2flg_last = -1;
knzw 0:a5b12f5693c6 151 while(1){
knzw 0:a5b12f5693c6 152 if(layer2flg_last!=layer2flg){
knzw 0:a5b12f5693c6 153 if(layer2flg==0){
knzw 0:a5b12f5693c6 154 ascii_font.DrawStr(ChooseTheme(num), 0, 0 , 0x0000ffff, 2);//白
knzw 0:a5b12f5693c6 155 }else{
knzw 0:a5b12f5693c6 156 memset(user_frame_buffer_string,0,sizeof(user_frame_buffer_string));
knzw 0:a5b12f5693c6 157 }
knzw 0:a5b12f5693c6 158 dcache_clean(user_frame_buffer_string,sizeof(user_frame_buffer_string));
knzw 0:a5b12f5693c6 159 layer2flg_last=layer2flg;
knzw 0:a5b12f5693c6 160 }
knzw 0:a5b12f5693c6 161 ThisThread::sleep_for(50);
knzw 0:a5b12f5693c6 162 }
knzw 0:a5b12f5693c6 163 }
knzw 0:a5b12f5693c6 164 #endif
knzw 0:a5b12f5693c6 165
knzw 0:a5b12f5693c6 166 static void draw_touch_pos(uint8_t * p_buf, int id, int drawpoint,int x, int y) { //バッファ,色,線の太さ,x座標,y座標
knzw 0:a5b12f5693c6 167 int idx_base;
knzw 0:a5b12f5693c6 168 int wk_idx;
knzw 0:a5b12f5693c6 169 int i;
knzw 0:a5b12f5693c6 170 int j;
knzw 0:a5b12f5693c6 171 uint8_t coller_pix[TOUCH_BUFFER_BYTE_PER_PIXEL]; /* ARGB4444 */
knzw 0:a5b12f5693c6 172
knzw 0:a5b12f5693c6 173 /* A coordinate in the upper left is calculated from a central coordinate. */
knzw 0:a5b12f5693c6 174 if ((x - (drawpoint / 2)) >= 0) {
knzw 0:a5b12f5693c6 175 x -= (drawpoint / 2);
knzw 0:a5b12f5693c6 176 }
knzw 0:a5b12f5693c6 177 if (x > ((int)LCD_PIXEL_WIDTH - drawpoint)) {
knzw 0:a5b12f5693c6 178 x = ((int)LCD_PIXEL_WIDTH - drawpoint);
knzw 0:a5b12f5693c6 179 }
knzw 0:a5b12f5693c6 180 if ((y - (drawpoint / 2)) >= 0) {
knzw 0:a5b12f5693c6 181 y -= (drawpoint / 2);
knzw 0:a5b12f5693c6 182 }
knzw 0:a5b12f5693c6 183 if (y > ((int)LCD_PIXEL_HEIGHT - drawpoint)) {
knzw 0:a5b12f5693c6 184 y = ((int)LCD_PIXEL_HEIGHT - drawpoint);
knzw 0:a5b12f5693c6 185 }
knzw 0:a5b12f5693c6 186 idx_base = (x + ((int)LCD_PIXEL_WIDTH * y)) * TOUCH_BUFFER_BYTE_PER_PIXEL;
knzw 0:a5b12f5693c6 187
knzw 0:a5b12f5693c6 188 /* Select color */
knzw 0:a5b12f5693c6 189 if (id == 0) {
knzw 0:a5b12f5693c6 190 /* Blue */
knzw 0:a5b12f5693c6 191 coller_pix[0] = 0x0F; /* 4:Green 4:Blue */
knzw 0:a5b12f5693c6 192 coller_pix[1] = 0xF0; /* 4:Alpha 4:Red */
knzw 0:a5b12f5693c6 193 } else if (id == 1){
knzw 0:a5b12f5693c6 194
knzw 0:a5b12f5693c6 195 /* black */
knzw 0:a5b12f5693c6 196 coller_pix[0] = 0x00; /* 4:Green 4:Blue */
knzw 0:a5b12f5693c6 197 coller_pix[1] = 0x00; /* 4:Alpha 4:Red */
knzw 0:a5b12f5693c6 198 } else {
knzw 0:a5b12f5693c6 199 /* red */
knzw 0:a5b12f5693c6 200 coller_pix[0] = 0x01;
knzw 0:a5b12f5693c6 201 coller_pix[1] = 0xFF;
knzw 0:a5b12f5693c6 202 }
knzw 0:a5b12f5693c6 203
knzw 0:a5b12f5693c6 204 /* Drawing */
knzw 0:a5b12f5693c6 205 for (i = 0; i < drawpoint; i++) {
knzw 0:a5b12f5693c6 206 wk_idx = idx_base + ((int)LCD_PIXEL_WIDTH * TOUCH_BUFFER_BYTE_PER_PIXEL * i);
knzw 0:a5b12f5693c6 207 for (j = 0; j < drawpoint; j++) {
knzw 0:a5b12f5693c6 208 p_buf[wk_idx++] = coller_pix[0];
knzw 0:a5b12f5693c6 209 p_buf[wk_idx++] = coller_pix[1];
knzw 0:a5b12f5693c6 210 }
knzw 0:a5b12f5693c6 211 }
knzw 0:a5b12f5693c6 212 }
knzw 0:a5b12f5693c6 213 #endif
knzw 0:a5b12f5693c6 214
knzw 0:a5b12f5693c6 215
knzw 0:a5b12f5693c6 216 static void DrawLine(int32_t x1,int32_t y1,int32_t x2, int32_t y2,int drawpoint){
knzw 0:a5b12f5693c6 217 int32_t dx=x2-x1;
knzw 0:a5b12f5693c6 218 int32_t dy=y2-y1;
knzw 0:a5b12f5693c6 219 int32_t sx=1;
knzw 0:a5b12f5693c6 220 int32_t sy=1;
knzw 0:a5b12f5693c6 221 int32_t i;
knzw 0:a5b12f5693c6 222 int32_t de;
knzw 0:a5b12f5693c6 223
knzw 0:a5b12f5693c6 224 if(dx<0){
knzw 0:a5b12f5693c6 225 dx *= -1;
knzw 0:a5b12f5693c6 226 sx *= -1;
knzw 0:a5b12f5693c6 227 }
knzw 0:a5b12f5693c6 228
knzw 0:a5b12f5693c6 229 if(dy<0){
knzw 0:a5b12f5693c6 230 dy*=-1;
knzw 0:a5b12f5693c6 231 sy*=-1;
knzw 0:a5b12f5693c6 232 }
knzw 0:a5b12f5693c6 233 draw_touch_pos(user_frame_buffer1,clr,drawpoint,x1,y1);
knzw 0:a5b12f5693c6 234
knzw 0:a5b12f5693c6 235 if(dx>dy){
knzw 0:a5b12f5693c6 236 for(i=dx,de=i/2;i;i--){
knzw 0:a5b12f5693c6 237 x1+=sx;
knzw 0:a5b12f5693c6 238 de+=dy;
knzw 0:a5b12f5693c6 239 if(de>dx){
knzw 0:a5b12f5693c6 240 de-=dx;
knzw 0:a5b12f5693c6 241 y1+=sy;
knzw 0:a5b12f5693c6 242 }
knzw 0:a5b12f5693c6 243 draw_touch_pos(user_frame_buffer1,clr,drawpoint,x1,y1);
knzw 0:a5b12f5693c6 244 }
knzw 0:a5b12f5693c6 245 }else{
knzw 0:a5b12f5693c6 246 for(i=dy,de=i/2;i;i--){
knzw 0:a5b12f5693c6 247 y1+=sy;
knzw 0:a5b12f5693c6 248 de+=dx;
knzw 0:a5b12f5693c6 249 if(de>dy){
knzw 0:a5b12f5693c6 250 de-=dy;
knzw 0:a5b12f5693c6 251 x1+=sx;
knzw 0:a5b12f5693c6 252 }
knzw 0:a5b12f5693c6 253 draw_touch_pos(user_frame_buffer1,clr,drawpoint,x1,y1);
knzw 0:a5b12f5693c6 254 }
knzw 0:a5b12f5693c6 255 }
knzw 0:a5b12f5693c6 256 }
knzw 0:a5b12f5693c6 257
knzw 0:a5b12f5693c6 258
knzw 0:a5b12f5693c6 259 void skip_btn_fall0(void){
knzw 0:a5b12f5693c6 260 //sta=(sta+1)%2; //on=1,off=0;
knzw 0:a5b12f5693c6 261
knzw 0:a5b12f5693c6 262 if(firstflg==0 || (layer2flg==1 && sta==0)){
knzw 0:a5b12f5693c6 263 layer2flg=0;
knzw 0:a5b12f5693c6 264 sta=1;
knzw 0:a5b12f5693c6 265 firstflg=1;
knzw 0:a5b12f5693c6 266 }else{
knzw 0:a5b12f5693c6 267 layer2flg=1;//非表示
knzw 0:a5b12f5693c6 268 sta=0;//off
knzw 0:a5b12f5693c6 269 }
knzw 0:a5b12f5693c6 270 }
knzw 0:a5b12f5693c6 271
knzw 0:a5b12f5693c6 272 void skip_btn_fall1(void){
knzw 0:a5b12f5693c6 273 clr=(clr+1)%2; //on=1,off=0; //消しゴム(黒色)と青色色分け
knzw 0:a5b12f5693c6 274 }
knzw 0:a5b12f5693c6 275
knzw 0:a5b12f5693c6 276 static void main_task(void) {
knzw 0:a5b12f5693c6 277 cv::Mat prev_image;
knzw 0:a5b12f5693c6 278 cv::Mat curr_image;
knzw 0:a5b12f5693c6 279 std::vector<cv::Point2f> prev_pts;
knzw 0:a5b12f5693c6 280 std::vector<cv::Point2f> curr_pts;
knzw 0:a5b12f5693c6 281 cv::Point2f point;
knzw 0:a5b12f5693c6 282 int16_t x = 0;
knzw 0:a5b12f5693c6 283 int16_t y = 0;
knzw 0:a5b12f5693c6 284
knzw 0:a5b12f5693c6 285
knzw 0:a5b12f5693c6 286 EasyAttach_Init(Display);
knzw 0:a5b12f5693c6 287 Start_Video_Camera();
knzw 0:a5b12f5693c6 288 #if MBED_CONF_APP_LCD
knzw 0:a5b12f5693c6 289 Start_LCD_Display();
knzw 0:a5b12f5693c6 290 #endif
knzw 0:a5b12f5693c6 291
knzw 0:a5b12f5693c6 292 #if STRING_DISP_TEST
knzw 0:a5b12f5693c6 293 //string
knzw 0:a5b12f5693c6 294 Thread stringTask;
knzw 0:a5b12f5693c6 295 stringTask.start(callback(string_task));
knzw 0:a5b12f5693c6 296 #endif // STRING_DISP_TEST
knzw 0:a5b12f5693c6 297
knzw 0:a5b12f5693c6 298 // Initialization of optical flow
knzw 0:a5b12f5693c6 299 point.y = (VIDEO_PIXEL_VW / 2) + (PLOT_INTERVAL * 1);
knzw 0:a5b12f5693c6 300 for (int32_t i = 0; i < 3; i++) {
knzw 0:a5b12f5693c6 301 point.x = (VIDEO_PIXEL_HW / 2) - (PLOT_INTERVAL * 1);
knzw 0:a5b12f5693c6 302 for (int32_t j = 0; j < 3; j++) {
knzw 0:a5b12f5693c6 303 prev_pts.push_back(point);
knzw 0:a5b12f5693c6 304 point.x += PLOT_INTERVAL;
knzw 0:a5b12f5693c6 305 }
knzw 0:a5b12f5693c6 306 point.y -= PLOT_INTERVAL;
knzw 0:a5b12f5693c6 307 }
knzw 0:a5b12f5693c6 308 skip_btn0.fall(&skip_btn_fall0);
knzw 0:a5b12f5693c6 309 skip_btn1.fall(&skip_btn_fall1);
knzw 0:a5b12f5693c6 310
knzw 0:a5b12f5693c6 311 #if MBED_CONF_APP_LCD
knzw 0:a5b12f5693c6 312 int16_t posx=LCD_PIXEL_WIDTH/2;
knzw 0:a5b12f5693c6 313 int16_t posy=LCD_PIXEL_HEIGHT/2;
knzw 0:a5b12f5693c6 314 int16_t prex=0;
knzw 0:a5b12f5693c6 315 int16_t prey=0;
knzw 0:a5b12f5693c6 316 int16_t akax=0;
knzw 0:a5b12f5693c6 317 int16_t akay=0;
knzw 0:a5b12f5693c6 318
knzw 0:a5b12f5693c6 319 while (1) {
knzw 0:a5b12f5693c6 320 // Wait for image input
knzw 0:a5b12f5693c6 321 wait_new_image();
knzw 0:a5b12f5693c6 322
knzw 0:a5b12f5693c6 323 // Convert from YUV422 to grayscale
knzw 0:a5b12f5693c6 324 cv::Mat img_yuv(VIDEO_PIXEL_VW, VIDEO_PIXEL_HW, CV_8UC2, user_frame_buffer0);
knzw 0:a5b12f5693c6 325 cv::cvtColor(img_yuv, curr_image, cv::COLOR_YUV2GRAY_YUY2);
knzw 0:a5b12f5693c6 326
knzw 0:a5b12f5693c6 327 point = cv::Point2f(0, 0);
knzw 0:a5b12f5693c6 328 if ((!curr_image.empty()) && (!prev_image.empty())) {
knzw 0:a5b12f5693c6 329 // Optical flow
knzw 0:a5b12f5693c6 330 std::vector<uchar> status;
knzw 0:a5b12f5693c6 331 std::vector<float> err;
knzw 0:a5b12f5693c6 332 cv::calcOpticalFlowPyrLK(prev_image, curr_image, prev_pts, curr_pts, status, err, cv::Size(21, 21), 0);
knzw 0:a5b12f5693c6 333
knzw 0:a5b12f5693c6 334 // Setting movement distance of feature point
knzw 0:a5b12f5693c6 335 std::vector<cv::Scalar> samples;
knzw 0:a5b12f5693c6 336 for (size_t i = 0; i < (size_t)status.size(); i++) {
knzw 0:a5b12f5693c6 337 if (status[i]) {
knzw 0:a5b12f5693c6 338 cv::Point2f vec = curr_pts[i] - prev_pts[i];
knzw 0:a5b12f5693c6 339 cv::Scalar sample = cv::Scalar(vec.x, vec.y);
knzw 0:a5b12f5693c6 340 samples.push_back(sample);
knzw 0:a5b12f5693c6 341 }
knzw 0:a5b12f5693c6 342 }
knzw 0:a5b12f5693c6 343
knzw 0:a5b12f5693c6 344 // Mean and standard deviation
knzw 0:a5b12f5693c6 345 if (samples.size() >= 6) {
knzw 0:a5b12f5693c6 346 cv::Scalar mean;
knzw 0:a5b12f5693c6 347 cv::Scalar stddev;
knzw 0:a5b12f5693c6 348 cv::meanStdDev((cv::InputArray)samples, mean, stddev);
knzw 0:a5b12f5693c6 349 //printf("%d, stddev=%lf, %lf\r\n", samples.size(), stddev[0], stddev[1]); // for debug
knzw 0:a5b12f5693c6 350 if ((stddev[0] < 10.0) && (stddev[1] < 10.0)) {
knzw 0:a5b12f5693c6 351 point.x = mean[0];
knzw 0:a5b12f5693c6 352 point.y = mean[1];
knzw 0:a5b12f5693c6 353 }
knzw 0:a5b12f5693c6 354 }
knzw 0:a5b12f5693c6 355 }
knzw 0:a5b12f5693c6 356 cv::swap(prev_image, curr_image);
knzw 0:a5b12f5693c6 357
knzw 0:a5b12f5693c6 358 x = (int16_t)(point.x * DIST_SCALE_FACTOR_X) *- 1;
knzw 0:a5b12f5693c6 359 y = (int16_t)(point.y * DIST_SCALE_FACTOR_Y) * -1;
knzw 0:a5b12f5693c6 360
knzw 0:a5b12f5693c6 361 if(sta==1){
knzw 0:a5b12f5693c6 362 //xとyは移動量なので、現在地を算出する
knzw 0:a5b12f5693c6 363 //その前に現在地を保存
knzw 0:a5b12f5693c6 364 prex=posx;//移動前
knzw 0:a5b12f5693c6 365 prey=posy;//移動前
knzw 0:a5b12f5693c6 366 posx+=x;//移動後
knzw 0:a5b12f5693c6 367 posy+=y;//移動後
knzw 0:a5b12f5693c6 368 }
knzw 0:a5b12f5693c6 369 //displayの外にはみでていたらdisplayの枠に値を矯正
knzw 0:a5b12f5693c6 370 posx=RangeCorr(posx,(int)LCD_PIXEL_WIDTH,0);
knzw 0:a5b12f5693c6 371 posy=RangeCorr(posy,(int)LCD_PIXEL_HEIGHT,0);
knzw 0:a5b12f5693c6 372
knzw 0:a5b12f5693c6 373 #endif
knzw 0:a5b12f5693c6 374 if ((x != 0) || (y != 0)) {
knzw 0:a5b12f5693c6 375 led1 = 1;
knzw 0:a5b12f5693c6 376 //printf("x=%d, y=%d\r\n", x, y); // for debug
knzw 0:a5b12f5693c6 377 #if MBED_CONF_APP_LCD
knzw 0:a5b12f5693c6 378 if(sta==1){//ub0のボタンが奇数回(1,,3, 5,・・・)押下されたら、線を描画する。(on,offスイッチ)
knzw 0:a5b12f5693c6 379 if(clr==1){
knzw 0:a5b12f5693c6 380 //円を描画して消す
knzw 0:a5b12f5693c6 381 draw_touch_pos(user_frame_buffer1,clr,ERASER_POINT,prex,prey); //前の座標を消去
knzw 0:a5b12f5693c6 382 DrawLine(prex,prey,posx,posy,ERASER_POINT);
knzw 0:a5b12f5693c6 383 draw_touch_pos(user_frame_buffer1,2,ERASER_POINT,posx,posy);
knzw 0:a5b12f5693c6 384 akax=posx;
knzw 0:a5b12f5693c6 385 akay=posy;
knzw 0:a5b12f5693c6 386
knzw 0:a5b12f5693c6 387 kesiflg=1;
knzw 0:a5b12f5693c6 388
knzw 0:a5b12f5693c6 389 //ThisThread::sleep_for(5);
knzw 0:a5b12f5693c6 390 //draw_touch_pos(user_frame_buffer1,clr,ERASER_POINT,posx,posy); //消しゴム
knzw 0:a5b12f5693c6 391 }else{
knzw 0:a5b12f5693c6 392 if(kesiflg==1){
knzw 0:a5b12f5693c6 393 draw_touch_pos(user_frame_buffer1,1,ERASER_POINT,akax,akay);
knzw 0:a5b12f5693c6 394 kesiflg=0;
knzw 0:a5b12f5693c6 395 }
knzw 0:a5b12f5693c6 396 draw_touch_pos(user_frame_buffer1,clr,DRAW_POINT,posx,posy); //ペン
knzw 0:a5b12f5693c6 397 DrawLine(prex,prey,posx,posy,DRAW_POINT);
knzw 0:a5b12f5693c6 398 }
knzw 0:a5b12f5693c6 399 }
knzw 0:a5b12f5693c6 400
knzw 0:a5b12f5693c6 401
knzw 0:a5b12f5693c6 402 #endif
knzw 0:a5b12f5693c6 403 } else {
knzw 0:a5b12f5693c6 404 led1 = 0;
knzw 0:a5b12f5693c6 405 }
knzw 0:a5b12f5693c6 406 }
knzw 0:a5b12f5693c6 407 }
knzw 0:a5b12f5693c6 408
knzw 0:a5b12f5693c6 409 #if MBED_CONF_APP_LCD
knzw 0:a5b12f5693c6 410 //範囲の修正
knzw 0:a5b12f5693c6 411 int16_t RangeCorr(int16_t target ,int16_t uplimit,int16_t lowlimit){
knzw 0:a5b12f5693c6 412 if(target>=lowlimit && target<=uplimit){ //もし範囲内だったら
knzw 0:a5b12f5693c6 413 return target;//そのまま返す
knzw 0:a5b12f5693c6 414 }else if(target>uplimit){ //上限より値が大きかったら
knzw 0:a5b12f5693c6 415 return uplimit; //上限の値を返す
knzw 0:a5b12f5693c6 416 }else{ //下限より小さかったら
knzw 0:a5b12f5693c6 417 return lowlimit; //下限の値を返す
knzw 0:a5b12f5693c6 418 }
knzw 0:a5b12f5693c6 419 }
knzw 0:a5b12f5693c6 420 #endif
knzw 0:a5b12f5693c6 421
knzw 0:a5b12f5693c6 422
knzw 0:a5b12f5693c6 423 uint8_t get_random(void){
knzw 0:a5b12f5693c6 424 size_t olen;
knzw 0:a5b12f5693c6 425 uint8_t data;
knzw 0:a5b12f5693c6 426 trng_t trng_obj;
knzw 0:a5b12f5693c6 427 static bool init_flg = false;
knzw 0:a5b12f5693c6 428
knzw 0:a5b12f5693c6 429 trng_init(&trng_obj);
knzw 0:a5b12f5693c6 430 if (init_flg == false) {
knzw 0:a5b12f5693c6 431 init_flg = true;
knzw 0:a5b12f5693c6 432 trng_get_bytes(&trng_obj, &data, 1, &olen);
knzw 0:a5b12f5693c6 433 }
knzw 0:a5b12f5693c6 434 trng_get_bytes(&trng_obj, &data, 1, &olen);
knzw 0:a5b12f5693c6 435 trng_free(&trng_obj);
knzw 0:a5b12f5693c6 436 return data;
knzw 0:a5b12f5693c6 437 }
knzw 0:a5b12f5693c6 438
knzw 0:a5b12f5693c6 439 int main(void) {
knzw 0:a5b12f5693c6 440 mainTask.start(callback(main_task));
knzw 0:a5b12f5693c6 441 mainTask.join();
knzw 0:a5b12f5693c6 442
knzw 0:a5b12f5693c6 443 }
knzw 0:a5b12f5693c6 444