Translate

ESP32 Cam Deteksi Object / Benda

ESP32 Cam Deteksi Object / Benda


        Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah ESP32 Cam dapat mendeteksi object yang berada di epannya. untuk contoh pada video kali ini objectnya yaitu bola, lampu dan spidol yang mana masihng2 memiliki size yang berbeda. untuk detailnya berikut kodingnya.
 
 
1. Interface
 

 
 2. Program ESP32 Cam
 
 #include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>
#include <Preferences.h>


//================ WIFI =================

const char* ssid = "ESP32-OBJECT";
const char* password = "12345678";

WebServer server(80);

Preferences memory;


//================ AI THINKER CAMERA =================

#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1

#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5

#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22



//================ DATA OBJECT =================


struct ObjectData
{
  bool aktif;

  float area;

  float ratio;

  float red;

  float green;

  float blue;
};



ObjectData data[4];


String namaObject[4]=
{
  "BOLA",
  "SPIDOL",
  "LAMPU",
  "UNKNOWN"
};



String hasil="BELUM ADA";

float areaNow=0;
float ratioNow=0;

float rNow=0;
float gNow=0;
float bNow=0;

int confidence=0;



unsigned long timer=0;



//================ SIMPAN =================


void saveData(int id)
{

memory.begin("object",false);

String key="d"+String(id);


memory.putBytes(
key.c_str(),
&data[id],
sizeof(ObjectData)
);


memory.end();

}



//================ LOAD =================


void loadData()
{

memory.begin("object",true);


for(int i=0;i<4;i++)
{

String key="d"+String(i);


memory.getBytes(
key.c_str(),
&data[i],
sizeof(ObjectData)
);

}


memory.end();

}



//================ RESET =================


void resetData()
{

for(int i=0;i<4;i++)
{

data[i].aktif=false;

}


memory.begin("object",false);

memory.clear();

memory.end();


}



//================ BACA OBJECT =================


void bacaObject()
{


camera_fb_t *fb =
esp_camera_fb_get();


if(!fb)
return;



int total=0;

long R=0;
long G=0;
long B=0;



int minX=320;
int maxX=0;

int minY=240;
int maxY=0;



for(int y=0;y<fb->height;y+=2)
{

for(int x=0;x<fb->width;x+=2)
{


int index=(y*fb->width+x)*2;



uint16_t pixel =
(fb->buf[index]<<8)
|
fb->buf[index+1];



int r =
((pixel>>11)&31)*255/31;


int g =
((pixel>>5)&63)*255/63;


int b =
(pixel&31)*255/31;



// object beda warna dari background

if(
abs(r-g)>20 ||
abs(g-b)>20 ||
abs(r-b)>20
)

{


total++;


R+=r;

G+=g;

B+=b;



if(x<minX) minX=x;

if(x>maxX) maxX=x;

if(y<minY) minY=y;

if(y>maxY) maxY=y;


}


}

}



if(total>20)
{


areaNow=total;


rNow=R/total;

gNow=G/total;

bNow=B/total;



float w=maxX-minX;

float h=maxY-minY;



if(h>0)

ratioNow=w/h;


klasifikasi();


}

else

{

hasil="TIDAK ADA";

confidence=0;

}



esp_camera_fb_return(fb);


}



//================ KLASIFIKASI =================


void klasifikasi()
{


float best=99999;

int index=-1;



for(int i=0;i<4;i++)

{


if(!data[i].aktif)
continue;



float nilai=0;



nilai += abs(areaNow-data[i].area)/100;


nilai += abs(ratioNow-data[i].ratio)*20;


nilai += abs(rNow-data[i].red)/20;


nilai += abs(gNow-data[i].green)/20;


nilai += abs(bNow-data[i].blue)/20;



if(nilai<best)

{

best=nilai;

index=i;

}


}



if(index>=0)

{


confidence=
100-(best*5);



if(confidence<0)
confidence=0;



if(confidence>100)
confidence=100;



hasil=namaObject[index];


}

else

{

hasil="UNKNOWN";

confidence=0;

}



}



//================ KALIBRASI =================


void kalibrasi()
{


if(!server.hasArg("objek"))
return;



String obj=
server.arg("objek");



int id=-1;



if(obj=="BOLA") id=0;

if(obj=="SPIDOL") id=1;

if(obj=="LAMPU") id=2;

if(obj=="UNKNOWN") id=3;



if(id>=0)

{


data[id].aktif=true;

data[id].area=areaNow;

data[id].ratio=ratioNow;

data[id].red=rNow;

data[id].green=gNow;

data[id].blue=bNow;


saveData(id);


}



server.send(
200,
"text/plain",
"KALIBRASI OK "+obj
);


}



//================ DATA JSON =================


void dataJSON()
{


String json="{";


json+="\"hasil\":\""+hasil+"\",";


json+="\"confidence\":"+String(confidence)+",";


json+="\"area\":"+String(areaNow);


json+="}";



server.send(
200,
"application/json",
json
);


}



//================ WEB =================


void home()
{


String html=R"rawliteral(

<html>

<body style="text-align:center;font-family:Arial">


<h2>
ESP32 OBJECT DETECTOR
</h2>


<h1 id="hasil">
-
</h1>


<h3>
Confidence:
<span id="conf">
0
</span>%
</h3>


<h3>
Area:
<span id="area">
0
</span>
</h3>



<hr>


<h3>
KALIBRASI
</h3>


<button onclick="kal('BOLA')">
⚽ BOLA
</button>


<button onclick="kal('SPIDOL')">
🖊️ SPIDOL
</button>


<button onclick="kal('LAMPU')">
💡 LAMPU
</button>


<button onclick="kal('UNKNOWN')">
UNKNOWN
</button>



<br><br>


<button onclick="reset()">
RESET
</button>



<script>


setInterval(()=>{


fetch('/data')

.then(r=>r.json())

.then(d=>{


hasil.innerHTML=d.hasil;

conf.innerHTML=d.confidence;

area.innerHTML=d.area;


});


},500);



function kal(x)
{

fetch('/kal?objek='+x);

}


function reset()
{

fetch('/reset');

}



</script>


</body>

</html>

)rawliteral";



server.send(
200,
"text/html",
html
);


}



//================ SETUP =================


void setup()
{


Serial.begin(115200);



camera_config_t config;


config.ledc_channel=LEDC_CHANNEL_0;

config.ledc_timer=LEDC_TIMER_0;



config.pin_d0=Y2_GPIO_NUM;
config.pin_d1=Y3_GPIO_NUM;
config.pin_d2=Y4_GPIO_NUM;
config.pin_d3=Y5_GPIO_NUM;
config.pin_d4=Y6_GPIO_NUM;
config.pin_d5=Y7_GPIO_NUM;
config.pin_d6=Y8_GPIO_NUM;
config.pin_d7=Y9_GPIO_NUM;


config.pin_xclk=XCLK_GPIO_NUM;

config.pin_pclk=PCLK_GPIO_NUM;

config.pin_vsync=VSYNC_GPIO_NUM;

config.pin_href=HREF_GPIO_NUM;


config.pin_sscb_sda=SIOD_GPIO_NUM;

config.pin_sscb_scl=SIOC_GPIO_NUM;


config.pin_pwdn=PWDN_GPIO_NUM;

config.pin_reset=RESET_GPIO_NUM;


config.xclk_freq_hz=20000000;


config.pixel_format=PIXFORMAT_RGB565;


config.frame_size=FRAMESIZE_QQVGA;


config.fb_count=1;



esp_camera_init(&config);



loadData();



WiFi.mode(WIFI_AP);


WiFi.softAP(
ssid,
password
);



Serial.println(
WiFi.softAPIP()
);



server.on("/",home);

server.on("/data",dataJSON);

server.on("/kal",kalibrasi);


server.on("/reset",[](){

resetData();

server.send(
200,
"text/plain",
"RESET"
);

});


server.begin();


}



//================ LOOP =================


void loop()
{

server.handleClient();


if(millis()-timer>700)

{

bacaObject();

timer=millis();

}


}
 
 
 
3. VIDEO HASILNYA
 

No comments:

Post a Comment