This is a pictionary that uses a camera to draw.

このページは2019/09/07時点のものです。それ以降のバージョンは操作方法が変更されている場合があります。

概要

Troubleshooting!

このプログラムは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:
Thu Oct 03 11:51:37 2019 +0000
Revision:
5:afca26898402
Parent:
4:5add66261b25
Fixed so that the red cursor does not appear in the eraser mode.(kesigomu mode no toki ni akai ka-soru ga kienaiyouni shuusei)

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