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
Swap
Target
thiefsil/camera-node
Select target project
thiefsil/camera-node
1 result
d900d81b6ce6383b82f26db3f2576c334ab2ceb9
Select Git revision
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
5 months ago
d61f0106
chore: recovery shell script 수정
· 954fa42b
한동현
authored
5 months ago
954fa42b
Hide 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 @@
#include
<unistd.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<libcamera/libcamera.h>
#include
<opencv2/opencv.hpp>
#include
<iomanip>
#include
<stdexcept>
...
...
@@ -19,12 +18,11 @@
#include
<arpa/inet.h>
using
namespace
std
;
using
namespace
libcamera
;
using
namespace
GPIO
;
#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 POUT 535 // 초음파 트리거 핀 (GPIO23)
...
...
@@ -71,86 +69,6 @@ int server_socket, python_socket; // 서버 소켓 및 파이썬 소켓
bool
detected
=
false
;
// 차량 감지 여부
bool
fireAlert
=
false
;
// 화재 경보 여부
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
)
{
for
(
size_t
idx
=
0
;
idx
<
rects
.
size
();
idx
++
)
{
...
...
@@ -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
)
{
const
FrameBuffer
*
buffer
=
request
->
buffers
().
begin
()
->
second
;
const
FrameBuffer
::
Plane
&
plane
=
buffer
->
planes
().
front
();
// 에코 핀 신호 대기
while
(
GPIORead
(
PIN
)
==
0
)
start_t
=
clock
();
while
(
GPIORead
(
PIN
)
==
1
)
end_t
=
clock
();
void
*
memory
=
mmap
(
nullptr
,
plane
.
length
,
PROT_READ
,
MAP_SHARED
,
plane
.
fd
.
get
(),
0
);
if
(
memory
!=
MAP_FAILED
)
{
cv
::
Mat
raw
(
800
,
1600
,
CV_8UC2
,
memory
);
cv
::
Mat
bgr
;
cv
::
cvtColor
(
raw
,
bgr
,
cv
::
COLOR_YUV2BGR_YUYV
);
double
time
=
(
double
)
(
end_t
-
start_t
)
/
CLOCKS_PER_SEC
;
// 시간 계산
double
distance
=
time
/
2
*
34000
;
// cm 단위 거리 계산
vector
<
unsigned
char
>
jpeg_buffer
;
vector
<
int
>
params
=
{
cv
::
IMWRITE_JPEG_QUALITY
,
90
};
cv
::
imencode
(
".jpg"
,
bgr
,
jpeg_buffer
,
params
);
cout
<<
distance
<<
"cm"
<<
endl
;
if
(
!
detected
&&
distance
<=
DISTANCE
)
{
// 10cm 이하 -> 차량 접근
detected
=
true
;
cout
<<
"차량 감지: "
<<
distance
<<
"cm"
<<
endl
;
// 현재 시간 타임스탬프
auto
now
=
chrono
::
system_clock
::
now
();
...
...
@@ -347,65 +300,28 @@ void requestComplete(Request* request) {
string
timestamp_str
=
timestamp
.
str
();
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
(
file
)
{
file
.
write
(
reinterpret_cast
<
char
*>
(
jpeg_buffer
.
data
()),
jpeg_buffer
.
size
());
file
.
close
();
if
(
system
(
cmd
.
c_str
())
==
0
)
{
cout
<<
"이미지 저장: "
<<
image_filename
<<
endl
;
}
else
{
cerr
<<
"이미지 저장 실패: "
<<
image_filename
<<
endl
;
}
munmap
(
memory
,
plane
.
length
);
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
()
{
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
;
// 서버 노드 소켓 생성
...
...
@@ -468,13 +384,6 @@ int main() {
close
(
python_socket
);
GPIOUnexport
(
POUT
);
GPIOUnexport
(
PIN
);
camera
->
requestCompleted
.
disconnect
();
camera
->
stop
();
camera
->
release
();
camera
.
reset
();
allocator
.
free
(
stream
);
cm
->
stop
();
}
catch
(
const
exception
&
e
)
{
cerr
<<
"Error: "
<<
e
.
what
()
<<
endl
;
return
1
;
...
...
This diff is collapsed.
Click to expand it.
recovery.sh
View file @
954fa42b
#!bin/bash
FILE_NAM
E
=
"camera"
SERVICE_FILE
=
"/etc/systemd/system/
${
FILE_NAME
}
.service"
FILE
_NAME2
=
"ocr"
SERVICE_FILE2
=
"/etc/systemd/system/
${
FILE_NAME2
}
.service"
CAMERA_FIL
E
=
"camera"
SERVICE_FILE
=
"/etc/systemd/system/
camera
.service"
OCR_
FILE
=
"ocr
.py
"
SERVICE_FILE2
=
"/etc/systemd/system/
ocr
.service"
USER_NAME
=
"pi"
EXEC
_PATH
=
"
.
/camera-node-control
/
${
FILE_NAME
}
.cpp
"
EXEC
_PATH
2
=
"
.
/camera-node-ocr
/
${
FILE_NAME2
}
.py
"
CAMERA
_PATH
=
"
$(
pwd
)
/camera-node-control"
OCR
_PATH
=
"
$(
pwd
)
/camera-node-ocr"
cat
<<
EOF
| sudo tee
$SERVICE_FILE
> /dev/null
[Unit]
Description=Camera
A
t
fer=network.target
Af
t
er=network.target
[Service]
ExecStart=
$EXEC_PATH
WorkingDirectory=
$CAMERA_PATH
ExecStart=
$CAMERA_PATH
/
$CAMERA_FILE
Restart=always
RestartSec=5s
User=
$USER_NAME
[Install]
WantedBy=multi-user.target
rpi
WantedBy=multi-user.target
EOF
sudo
systemctl daemon-reload
sudo
systemctl
enable
${
FILE_NAME
}
.service
sudo
systemctl start
${
FILE_NAME
}
.service
sudo
systemctl status
${
FILE_NAME
}
.service
sudo
systemctl
enable
camera
.service
sudo
systemctl start
camera
.service
sudo
systemctl status
camera
.service
cat
<<
EOF
| sudo tee
$SERVICE_FILE2
> /dev/null
[Unit]
Description=Ocr
A
t
fer=network.target
Af
t
er=network.target
[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
RestartSec=5s
User=
$USER_NAME
[Install]
WantedBy=multi-user.target
rpi
WantedBy=multi-user.target
EOF
sudo
systemctl daemon-reload
sudo
systemctl
enable
${
FILE_NAME2
}
.service
sudo
systemctl start
${
FILE_NAME2
}
.service
sudo
systemctl status
${
FILE_NAME2
}
.service
sudo
systemctl
enable
ocr
.service
sudo
systemctl start
ocr
.service
sudo
systemctl status
ocr
.service
This diff is collapsed.
Click to expand it.