Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
camera-node
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ThiefSil
camera-node
Compare revisions
d900d81b6ce6383b82f26db3f2576c334ab2ceb9 to 954fa42b8d15db5d06a8e35d7937f6c2f8444ee0
Compare revisions
Changes are shown as if the
source
revision was being merged into the
target
revision.
Learn more about comparing revisions.
Source
thiefsil/camera-node
Select target project
No results found
954fa42b8d15db5d06a8e35d7937f6c2f8444ee0
Select Git revision
Branches
master
1 result
Swap
Target
thiefsil/camera-node
Select target project
thiefsil/camera-node
1 result
d900d81b6ce6383b82f26db3f2576c334ab2ceb9
Select Git revision
Branches
master
1 result
Show changes
Only incoming changes from source
Include changes to target since source was created
Compare
Commits on Source (2)
refactor(c): libcamera 커맨드라인 명령으로 변경
· d61f0106
한동현
authored
6 months ago
d61f0106
chore: recovery shell script 수정
· 954fa42b
한동현
authored
5 months ago
954fa42b
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
camera-node-control/camera.cpp
+56
-147
56 additions, 147 deletions
camera-node-control/camera.cpp
recovery.sh
+22
-18
22 additions, 18 deletions
recovery.sh
with
78 additions
and
165 deletions
camera-node-control/camera.cpp
View file @
954fa42b
...
@@ -11,7 +11,6 @@
...
@@ -11,7 +11,6 @@
#include
<unistd.h>
#include
<unistd.h>
#include
<sys/socket.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<netinet/in.h>
#include
<libcamera/libcamera.h>
#include
<opencv2/opencv.hpp>
#include
<opencv2/opencv.hpp>
#include
<iomanip>
#include
<iomanip>
#include
<stdexcept>
#include
<stdexcept>
...
@@ -19,12 +18,11 @@
...
@@ -19,12 +18,11 @@
#include
<arpa/inet.h>
#include
<arpa/inet.h>
using
namespace
std
;
using
namespace
std
;
using
namespace
libcamera
;
using
namespace
GPIO
;
using
namespace
GPIO
;
#define BUFFER_SIZE 1024
#define BUFFER_SIZE 1024
#define SERVER_ADDR "1
27.0.0.1
"
#define SERVER_ADDR "1
92.168.121.4
"
#define SERVER_PORT 12345
#define SERVER_PORT 12345
#define POUT 535 // 초음파 트리거 핀 (GPIO23)
#define POUT 535 // 초음파 트리거 핀 (GPIO23)
...
@@ -71,86 +69,6 @@ int server_socket, python_socket; // 서버 소켓 및 파이썬 소켓
...
@@ -71,86 +69,6 @@ int server_socket, python_socket; // 서버 소켓 및 파이썬 소켓
bool
detected
=
false
;
// 차량 감지 여부
bool
detected
=
false
;
// 차량 감지 여부
bool
fireAlert
=
false
;
// 화재 경보 여부
bool
fireAlert
=
false
;
// 화재 경보 여부
pthread_t
sensor_thread
,
receive_thread
;
pthread_t
sensor_thread
,
receive_thread
;
shared_ptr
<
Camera
>
camera
;
unique_ptr
<
CameraManager
>
cm
;
unique_ptr
<
Request
>
request
;
// 서버 메시지 수신 스레드
void
*
receive_message
(
void
*
arg
)
{
char
buffer
[
BUFFER_SIZE
];
while
(
true
)
{
auto
read_bytes
=
read
(
server_socket
,
buffer
,
BUFFER_SIZE
-
1
);
if
(
read_bytes
<=
0
)
{
cout
<<
"서버와의 연결이 종료되었습니다."
<<
endl
;
close
(
server_socket
);
exit
(
0
);
}
buffer
[
read_bytes
]
=
'\0'
;
cout
<<
"서버로부터 받은 메시지: "
<<
buffer
<<
endl
;
string
msg
(
buffer
);
msg
=
msg
.
substr
(
0
,
msg
.
find_first_of
(
"
\r\n
"
));
if
(
msg
==
"0-FIRE"
)
{
fireAlert
=
true
;
cout
<<
"화재 경보가 발생했습니다."
<<
endl
;
}
else
if
(
msg
==
"0-CLEAR"
)
{
fireAlert
=
false
;
cout
<<
"화재 경보가 해제되었습니다."
<<
endl
;
}
}
return
nullptr
;
}
// 초음파 센서 측정 스레드
void
*
ultrasonic_sensor
(
void
*
arg
)
{
clock_t
start_t
,
end_t
;
while
(
1
)
{
// 초음파 센서 측정
GPIOWrite
(
POUT
,
Value
::
HIGH
);
usleep
(
10
);
GPIOWrite
(
POUT
,
Value
::
LOW
);
// 에코 핀 신호 대기
while
(
GPIORead
(
PIN
)
==
0
)
start_t
=
clock
();
while
(
GPIORead
(
PIN
)
==
1
)
end_t
=
clock
();
double
time
=
(
double
)
(
end_t
-
start_t
)
/
CLOCKS_PER_SEC
;
// 시간 계산
double
distance
=
time
/
2
*
34000
;
// cm 단위 거리 계산
cout
<<
distance
<<
"cm"
<<
endl
;
if
(
!
detected
&&
distance
<=
DISTANCE
)
{
// 10cm 이하 -> 차량 접근
detected
=
true
;
cout
<<
"차량 감지: "
<<
distance
<<
"cm"
<<
endl
;
// 카메라를 시작합니다.
if
(
camera
->
start
())
{
throw
runtime_error
(
"Failed to start camera"
);
}
// 카메라 촬영
if
(
camera
->
queueRequest
(
request
.
get
())
<
0
)
{
throw
runtime_error
(
"Failed to queue request"
);
}
this_thread
::
sleep_for
(
chrono
::
milliseconds
(
2000
));
// 카메라 종료
camera
->
stop
();
}
else
if
(
detected
&&
distance
>
10
)
{
// 10cm 초과 -> 차량 없음
detected
=
false
;
cout
<<
"차량 감지 해제"
<<
endl
;
}
usleep
(
500000
);
// 0.5초 주기
}
return
nullptr
;
}
vector
<
Rect
>
detect_character
(
const
vector
<
Rect
>&
rects
)
{
vector
<
Rect
>
detect_character
(
const
vector
<
Rect
>&
rects
)
{
for
(
size_t
idx
=
0
;
idx
<
rects
.
size
();
idx
++
)
{
for
(
size_t
idx
=
0
;
idx
<
rects
.
size
();
idx
++
)
{
...
@@ -323,21 +241,56 @@ void detect_plate(const string& img_path) {
...
@@ -323,21 +241,56 @@ void detect_plate(const string& img_path) {
}
}
}
}
// 서버 메시지 수신 스레드
void
*
receive_message
(
void
*
arg
)
{
char
buffer
[
BUFFER_SIZE
];
while
(
true
)
{
auto
read_bytes
=
read
(
server_socket
,
buffer
,
BUFFER_SIZE
-
1
);
if
(
read_bytes
<=
0
)
{
cout
<<
"서버와의 연결이 종료되었습니다."
<<
endl
;
close
(
server_socket
);
exit
(
0
);
}
buffer
[
read_bytes
]
=
'\0'
;
cout
<<
"서버로부터 받은 메시지: "
<<
buffer
<<
endl
;
string
msg
(
buffer
);
msg
=
msg
.
substr
(
0
,
msg
.
find_first_of
(
"
\r\n
"
));
if
(
msg
==
"0-FIRE"
)
{
fireAlert
=
true
;
cout
<<
"화재 경보가 발생했습니다."
<<
endl
;
}
else
if
(
msg
==
"0-CLEAR"
)
{
fireAlert
=
false
;
cout
<<
"화재 경보가 해제되었습니다."
<<
endl
;
}
}
return
nullptr
;
}
// 초음파 센서 측정 스레드
void
*
ultrasonic_sensor
(
void
*
arg
)
{
clock_t
start_t
,
end_t
;
while
(
1
)
{
// 초음파 센서 측정
GPIOWrite
(
POUT
,
Value
::
HIGH
);
usleep
(
10
);
GPIOWrite
(
POUT
,
Value
::
LOW
);
void
requestComplete
(
Request
*
request
)
{
// 에코 핀 신호 대기
if
(
request
->
status
()
==
Request
::
RequestComplete
)
{
while
(
GPIORead
(
PIN
)
==
0
)
start_t
=
clock
();
const
FrameBuffer
*
buffer
=
request
->
buffers
().
begin
()
->
second
;
while
(
GPIORead
(
PIN
)
==
1
)
end_t
=
clock
();
const
FrameBuffer
::
Plane
&
plane
=
buffer
->
planes
().
front
();
void
*
memory
=
mmap
(
nullptr
,
plane
.
length
,
PROT_READ
,
MAP_SHARED
,
plane
.
fd
.
get
(),
0
);
double
time
=
(
double
)
(
end_t
-
start_t
)
/
CLOCKS_PER_SEC
;
// 시간 계산
if
(
memory
!=
MAP_FAILED
)
{
double
distance
=
time
/
2
*
34000
;
// cm 단위 거리 계산
cv
::
Mat
raw
(
800
,
1600
,
CV_8UC2
,
memory
);
cv
::
Mat
bgr
;
cv
::
cvtColor
(
raw
,
bgr
,
cv
::
COLOR_YUV2BGR_YUYV
);
vector
<
unsigned
char
>
jpeg_buffer
;
cout
<<
distance
<<
"cm"
<<
endl
;
vector
<
int
>
params
=
{
cv
::
IMWRITE_JPEG_QUALITY
,
90
};
if
(
!
detected
&&
distance
<=
DISTANCE
)
{
// 10cm 이하 -> 차량 접근
cv
::
imencode
(
".jpg"
,
bgr
,
jpeg_buffer
,
params
);
detected
=
true
;
cout
<<
"차량 감지: "
<<
distance
<<
"cm"
<<
endl
;
// 현재 시간 타임스탬프
// 현재 시간 타임스탬프
auto
now
=
chrono
::
system_clock
::
now
();
auto
now
=
chrono
::
system_clock
::
now
();
...
@@ -347,65 +300,28 @@ void requestComplete(Request* request) {
...
@@ -347,65 +300,28 @@ void requestComplete(Request* request) {
string
timestamp_str
=
timestamp
.
str
();
string
timestamp_str
=
timestamp
.
str
();
string
image_filename
=
IMAGES_DIR
+
"/image_"
+
timestamp_str
+
".jpg"
;
string
image_filename
=
IMAGES_DIR
+
"/image_"
+
timestamp_str
+
".jpg"
;
string
cmd
=
"libcamera-still --nopreview --immediate --rotation=180 --width=1296 --height=972 --denoise off -t 1 -o "
+
image_filename
;
ofstream
file
(
image_filename
,
ios
::
binary
);
if
(
system
(
cmd
.
c_str
())
==
0
)
{
if
(
file
)
{
file
.
write
(
reinterpret_cast
<
char
*>
(
jpeg_buffer
.
data
()),
jpeg_buffer
.
size
());
file
.
close
();
cout
<<
"이미지 저장: "
<<
image_filename
<<
endl
;
cout
<<
"이미지 저장: "
<<
image_filename
<<
endl
;
}
else
{
}
else
{
cerr
<<
"이미지 저장 실패: "
<<
image_filename
<<
endl
;
cerr
<<
"이미지 저장 실패: "
<<
image_filename
<<
endl
;
}
}
munmap
(
memory
,
plane
.
length
);
detect_plate
(
image_filename
);
detect_plate
(
image_filename
);
}
else
if
(
detected
&&
distance
>
10
)
{
// 10cm 초과 -> 차량 없음
detected
=
false
;
cout
<<
"차량 감지 해제"
<<
endl
;
}
}
request
->
reuse
(
Request
::
ReuseBuffers
);
usleep
(
500000
);
// 0.5초 주기
}
}
return
nullptr
;
}
}
int
main
()
{
int
main
()
{
try
{
try
{
cm
=
make_unique
<
CameraManager
>
();
cm
->
start
();
auto
cameras
=
cm
->
cameras
();
if
(
cameras
.
empty
())
{
throw
runtime_error
(
"No cameras found!"
);
}
camera
=
cameras
[
0
];
camera
->
acquire
();
unique_ptr
<
CameraConfiguration
>
config
=
camera
->
generateConfiguration
({
StreamRole
::
StillCapture
});
config
->
orientation
=
Orientation
::
Rotate180
;
StreamConfiguration
&
streamConfig
=
config
->
at
(
0
);
streamConfig
.
size
=
Size
(
1600
,
900
);
streamConfig
.
pixelFormat
=
formats
::
YUYV
;
streamConfig
.
bufferCount
=
1
;
CameraConfiguration
::
Status
status
=
config
->
validate
();
if
(
status
!=
CameraConfiguration
::
Valid
)
{
throw
runtime_error
(
"Camera configuration invalid"
);
}
camera
->
configure
(
config
.
get
());
FrameBufferAllocator
allocator
(
camera
);
Stream
*
stream
=
streamConfig
.
stream
();
allocator
.
allocate
(
stream
);
camera
->
requestCompleted
.
connect
(
requestComplete
);
const
vector
<
unique_ptr
<
FrameBuffer
>>
&
buffers
=
allocator
.
buffers
(
stream
);
request
=
camera
->
createRequest
();
if
(
request
->
addBuffer
(
stream
,
buffers
.
at
(
0
).
get
())
<
0
)
{
throw
runtime_error
(
"Failed to add buffer to request"
);
}
struct
sockaddr_in
server_addr
,
python_addr
;
struct
sockaddr_in
server_addr
,
python_addr
;
// 서버 노드 소켓 생성
// 서버 노드 소켓 생성
...
@@ -468,13 +384,6 @@ int main() {
...
@@ -468,13 +384,6 @@ int main() {
close
(
python_socket
);
close
(
python_socket
);
GPIOUnexport
(
POUT
);
GPIOUnexport
(
POUT
);
GPIOUnexport
(
PIN
);
GPIOUnexport
(
PIN
);
camera
->
requestCompleted
.
disconnect
();
camera
->
stop
();
camera
->
release
();
camera
.
reset
();
allocator
.
free
(
stream
);
cm
->
stop
();
}
catch
(
const
exception
&
e
)
{
}
catch
(
const
exception
&
e
)
{
cerr
<<
"Error: "
<<
e
.
what
()
<<
endl
;
cerr
<<
"Error: "
<<
e
.
what
()
<<
endl
;
return
1
;
return
1
;
...
...
This diff is collapsed.
Click to expand it.
recovery.sh
View file @
954fa42b
#!bin/bash
#!bin/bash
FILE_NAM
E
=
"camera"
CAMERA_FIL
E
=
"camera"
SERVICE_FILE
=
"/etc/systemd/system/
${
FILE_NAME
}
.service"
SERVICE_FILE
=
"/etc/systemd/system/
camera
.service"
FILE
_NAME2
=
"ocr"
OCR_
FILE
=
"ocr
.py
"
SERVICE_FILE2
=
"/etc/systemd/system/
${
FILE_NAME2
}
.service"
SERVICE_FILE2
=
"/etc/systemd/system/
ocr
.service"
USER_NAME
=
"pi"
USER_NAME
=
"pi"
EXEC
_PATH
=
"
.
/camera-node-control
/
${
FILE_NAME
}
.cpp
"
CAMERA
_PATH
=
"
$(
pwd
)
/camera-node-control"
EXEC
_PATH
2
=
"
.
/camera-node-ocr
/
${
FILE_NAME2
}
.py
"
OCR
_PATH
=
"
$(
pwd
)
/camera-node-ocr"
cat
<<
EOF
| sudo tee
$SERVICE_FILE
> /dev/null
cat
<<
EOF
| sudo tee
$SERVICE_FILE
> /dev/null
[Unit]
[Unit]
Description=Camera
Description=Camera
A
t
fer=network.target
Af
t
er=network.target
[Service]
[Service]
ExecStart=
$EXEC_PATH
WorkingDirectory=
$CAMERA_PATH
ExecStart=
$CAMERA_PATH
/
$CAMERA_FILE
Restart=always
Restart=always
RestartSec=5s
User=
$USER_NAME
User=
$USER_NAME
[Install]
[Install]
WantedBy=multi-user.target
rpi
WantedBy=multi-user.target
EOF
EOF
sudo
systemctl daemon-reload
sudo
systemctl daemon-reload
sudo
systemctl
enable
${
FILE_NAME
}
.service
sudo
systemctl
enable
camera
.service
sudo
systemctl start
${
FILE_NAME
}
.service
sudo
systemctl start
camera
.service
sudo
systemctl status
${
FILE_NAME
}
.service
sudo
systemctl status
camera
.service
cat
<<
EOF
| sudo tee
$SERVICE_FILE2
> /dev/null
cat
<<
EOF
| sudo tee
$SERVICE_FILE2
> /dev/null
[Unit]
[Unit]
Description=Ocr
Description=Ocr
A
t
fer=network.target
Af
t
er=network.target
[Service]
[Service]
ExecStart=python3
$EXEC_PATH2
WorkingDirectory=
$OCR_PATH
ExecStart=/bin/bash -c "source
$OCR_PATH
/venv/bin/activate && python3
$OCR_PATH
/
$OCR_FILE
"
Restart=always
Restart=always
RestartSec=5s
User=
$USER_NAME
User=
$USER_NAME
[Install]
[Install]
WantedBy=multi-user.target
rpi
WantedBy=multi-user.target
EOF
EOF
sudo
systemctl daemon-reload
sudo
systemctl daemon-reload
sudo
systemctl
enable
${
FILE_NAME2
}
.service
sudo
systemctl
enable
ocr
.service
sudo
systemctl start
${
FILE_NAME2
}
.service
sudo
systemctl start
ocr
.service
sudo
systemctl status
${
FILE_NAME2
}
.service
sudo
systemctl status
ocr
.service
This diff is collapsed.
Click to expand it.