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
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ThiefSil
camera-node
Commits
d61f0106
Commit
d61f0106
authored
7 months ago
by
한동현
Browse files
Options
Downloads
Patches
Plain Diff
refactor(c): libcamera 커맨드라인 명령으로 변경
parent
d900d81b
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
camera-node-control/camera.cpp
+56
-147
56 additions, 147 deletions
camera-node-control/camera.cpp
with
56 additions
and
147 deletions
camera-node-control/camera.cpp
+
56
−
147
View file @
d61f0106
...
@@ -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.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment