bool
time_flag_0
=
false
;
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
>
start_0
,
end_0
;
bool
time_flag_1
=
false
;
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
>
start_1
,
end_1
;
std
::
queue
<
cv
::
Mat
>
img0_buf
;
std
::
queue
<
unsigned
int
>
frame0_ID_buf
;
std
::
queue
<
double
>
time0_buf
;
std
::
mutex m0_buf
;
std
::
queue
<
cv
::
Mat
>
img1_buf
;
std
::
queue
<
unsigned
int
>
frame1_ID_buf
;
std
::
queue
<
double
>
time1_buf
;
std
::
mutex m1_buf
;
#
define
image_width
640
#
define
image_height
480
char
*
pRGB24Buf_0
=
new
char
[
image_width
*
image_height
*
3
]
;
char
*
pRGB24Buf_1
=
new
char
[
image_width
*
image_height
*
3
]
;
void
Frame_0_ProcessRGB
(
GX_FRAME_CALLBACK_PARAM
*
pFrame
)
if
(
pFrame
->
status
==
GX_FRAME_STATUS_SUCCESS
)
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
,
std
::
chrono
::
microseconds
>
tp
=
std
::
chrono
::
time_point_cast
<
std
::
chrono
::
microseconds
>
(
std
::
chrono
::
system_clock
::
now
(
)
)
;
double
time_now
=
tp
.
time_since_epoch
(
)
.
count
(
)
;
start_0
=
std
::
chrono
::
system_clock
::
now
(
)
;
if
(
!
time_flag_0
)
end_0
=
start_0
;
time_flag_0
=
true
;
std
::
chrono
::
duration
<
double
>
elapsed_seconds
=
start_0
-
end_0
;
std
::
cout
<<
"the CAM_0 frame frequency is: "
<<
1
/
elapsed_seconds
.
count
(
)
<<
std
::
endl
;
end_0
=
start_0
;
memset
(
pRGB24Buf_0
,
0
,
pFrame
->
nWidth
*
pFrame
->
nHeight
*
3
*
sizeof
(
char
)
)
;
DX_BAYER_CONVERT_TYPE cvtype
=
RAW2RGB_NEIGHBOUR
;
DX_PIXEL_COLOR_FILTER nBayerType
=
BAYERRG
;
bool
bFlip
=
false
;
VxInt32 DxStatus
=
DxRaw8toRGB24
(
const_cast
<
void
*
>
(
pFrame
->
pImgBuf
)
,
pRGB24Buf_0
,
pFrame
->
nWidth
,
pFrame
->
nHeight
,
cvtype
,
nBayerType
,
bFlip
)
;
if
(
DxStatus
!=
DX_OK
)
return
;
cv
::
Mat
image_rgb24
(
pFrame
->
nHeight
,
pFrame
->
nWidth
,
CV_8UC3
)
;
memcpy
(
image_rgb24
.
data
,
pRGB24Buf_0
,
pFrame
->
nHeight
*
pFrame
->
nWidth
*
3
)
;
unsigned
int
frame_id
=
pFrame
->
nFrameID
;
m0_buf
.
lock
(
)
;
img0_buf
.
push
(
image_rgb24
)
;
frame0_ID_buf
.
push
(
frame_id
)
;
time0_buf
.
push
(
time_now
)
;
m0_buf
.
unlock
(
)
return
;
void
Frame_1_ProcessRGB
(
GX_FRAME_CALLBACK_PARAM
*
pFrame
)
if
(
pFrame
->
status
==
GX_FRAME_STATUS_SUCCESS
)
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
,
std
::
chrono
::
microseconds
>
tp
=
std
::
chrono
::
time_point_cast
<
std
::
chrono
::
microseconds
>
(
std
::
chrono
::
system_clock
::
now
(
)
)
;
double
time_now
=
tp
.
time_since_epoch
(
)
.
count
(
)
;
start_1
=
std
::
chrono
::
system_clock
::
now
(
)
;
if
(
!
time_flag_1
)
end_1
=
start_1
;
time_flag_1
=
true
;
std
::
chrono
::
duration
<
double
>
elapsed_seconds
=
start_1
-
end_1
;
std
::
cout
<<
"the CAM_1 frame frequency is: "
<<
1
/
elapsed_seconds
.
count
(
)
<<
std
::
endl
;
end_1
=
start_1
;
memset
(
pRGB24Buf_1
,
0
,
pFrame
->
nWidth
*
pFrame
->
nHeight
*
3
*
sizeof
(
char
)
)
;
DX_BAYER_CONVERT_TYPE cvtype
=
RAW2RGB_NEIGHBOUR
;
DX_PIXEL_COLOR_FILTER nBayerType
=
BAYERRG
;
bool
bFlip
=
false
;
VxInt32 DxStatus
=
DxRaw8toRGB24
(
const_cast
<
void
*
>
(
pFrame
->
pImgBuf
)
,
pRGB24Buf_1
,
pFrame
->
nWidth
,
pFrame
->
nHeight
,
cvtype
,
nBayerType
,
bFlip
)
;
if
(
DxStatus
!=
DX_OK
)
return
;
cv
::
Mat
image_rgb24
(
pFrame
->
nHeight
,
pFrame
->
nWidth
,
CV_8UC3
)
;
memcpy
(
image_rgb24
.
data
,
pRGB24Buf_1
,
pFrame
->
nHeight
*
pFrame
->
nWidth
*
3
)
;
unsigned
int
frame_id
=
pFrame
->
nFrameID
;
m1_buf
.
lock
(
)
;
img1_buf
.
push
(
image_rgb24
)
;
frame1_ID_buf
.
push
(
frame_id
)
;
time1_buf
.
push
(
time_now
)
;
m1_buf
.
unlock
(
)
;
return
;
void
cam0_process
(
)
int
cam0_num
=
0
;
while
(
1
)
cv
::
Mat img_frame
;
unsigned
int
id
=
0
;
double
time
=
0
;
m0_buf
.
lock
(
)
;
if
(
!
img0_buf
.
empty
(
)
)
std
::
cout
<<
"the img0_buf size is: "
<<
img0_buf
.
size
(
)
<<
std
::
endl
;
img_frame
=
img0_buf
.
front
(
)
.
clone
(
)
;
id
=
frame0_ID_buf
.
front
(
)
;
time
=
time0_buf
.
front
(
)
;
img0_buf
.
pop
(
)
;
frame0_ID_buf
.
pop
(
)
;
time0_buf
.
pop
(
)
;
m0_buf
.
unlock
(
)
;
if
(
img_frame
.
data
)
cvtColor
(
img_frame
,
img_frame
,
CV_BGR2RGB
)
;
std
::
string img0_path
=
"/home/h1/CODE/stereo_img_record/build/img0/"
+
std
::
to_string
(
cam0_num
++
)
+
".jpg"
;
std
::
cout
<<
img0_path
<<
std
::
endl
;
cv
::
imwrite
(
img0_path
,
img_frame
)
;
cv
::
waitKey
(
1
)
;
return
;
std
::
chrono
::
milliseconds
dura
(
1
)
;
std
::
this_thread
::
sleep_for
(
dura
)
;
void
cam1_process
(
)
int
cam1_num
=
1
;
while
(
1
)
cv
::
Mat img_frame
;
unsigned
int
id
=
0
;
double
time
=
0
;
m1_buf
.
lock
(
)
;
if
(
!
img1_buf
.
empty
(
)
)
img_frame
=
img1_buf
.
front
(
)
.
clone
(
)
;
id
=
frame1_ID_buf
.
front
(
)
;
time
=
time1_buf
.
front
(
)
;
img1_buf
.
pop
(
)
;
frame1_ID_buf
.
pop
(
)
;
time1_buf
.
pop
(
)
;
m1_buf
.
unlock
(
)
;
if
(
img_frame
.
data
)
cvtColor
(
img_frame
,
img_frame
,
CV_BGR2RGB
)
;
std
::
string img1_path
=
"/home/h1/CODE/stereo_img_record/build/img1/"
+
std
::
to_string
(
cam1_num
++
)
+
".jpg"
;
std
::
cout
<<
img1_path
<<
std
::
endl
;
cv
::
imwrite
(
img1_path
,
img_frame
)
;
cv
::
imshow
(
"img1:"
,
img_frame
)
;
return
;
std
::
chrono
::
milliseconds
dura
(
1
)
;
std
::
this_thread
::
sleep_for
(
dura
)
;
int
main
(
)
GX_STATUS status
=
Config
(
)
;
if
(
status
!=
GX_STATUS_SUCCESS
)
std
::
cout
<<
"config Camera Faile ..."
<<
std
::
endl
;
return
0
;
camera_config cam0_info
;
cam0_info
.
sn_str
=
"KE0200100061"
;
cam0_info
.
SN
=
&
cam0_info
.
sn_str
[
0
]
;
camera_config cam1_info
;
cam1_info
.
sn_str
=
"KE0200120158"
;
cam1_info
.
SN
=
&
cam1_info
.
sn_str
[
0
]
;
MercureDriver
*
cam0
=
new
MercureDriver
(
cam0_info
)
;
MercureDriver
*
cam1
=
new
MercureDriver
(
cam1_info
)
;
cam0
->
InitCamera
(
)
;
cam1
->
InitCamera
(
)
;
if
(
cam0
->
status
!=
GX_STATUS_SUCCESS
||
cam1
->
status
!=
GX_STATUS_SUCCESS
)
std
::
cout
<<
"Initial Stereo Camera Faile ..."
<<
std
::
endl
;
return
0
;
status
=
GXRegisterCaptureCallback
(
cam0
->
hDevice_
,
NULL
,
Frame_0_ProcessRGB
)
;
status
=
GXSendCommand
(
cam0
->
hDevice_
,
GX_COMMAND_ACQUISITION_START
)
;
if
(
status
!=
GX_STATUS_SUCCESS
)
std
::
cout
<<
"Cam0 Start Read Faile ..."
<<
std
::
endl
;
return
0
;
status
=
GXRegisterCaptureCallback
(
cam1
->
hDevice_
,
NULL
,
Frame_1_ProcessRGB
)
;
status
=
GXSendCommand
(
cam1
->
hDevice_
,
GX_COMMAND_ACQUISITION_START
)
;
if
(
status
!=
GX_STATUS_SUCCESS
)
std
::
cout
<<
"Cam1 Start Read Faile ..."
<<
std
::
endl
;
return
0
;
std
::
thread cam0_thread
{
cam0_process
}
;
std
::
thread cam1_thread
{
cam1_process
}
;
while
(
1
)
std
::
chrono
::
milliseconds
dura
(
5
)
;
std
::
this_thread
::
sleep_for
(
dura
)
;
return
0
;
display_fps.sprintf(“序列号: %s 显示帧率: %.2f FPS”, pf1->m_baseinfo[id].szSN, pf1->m_struct_camera[id].fps);device_name.sprintf(“
相机
: %s”, pf1->m_baseinfo[id].szDisplayName);//将Raw8图像转换为RGB图像以供显示。//若支持彩色,转换为RGB图像后输出。
最近刷知乎看到这样一个问题👇碰巧B站也有朋友在问这种类似的问题,我寻思刚开始接触深度
相机
的朋友们应该都会有这种疑问,所以我整理了一下这个内容。大家也可以去知乎看我的回答,别忘了三连哦~深度
相机
也被称为3D
相机
,它和普通2D
相机
的区别在于可以获取物体到
相机
的距离信息,加之2D平面的X,Y坐标,可计算出每个点的三维坐标,以此我们可推断深度
相机
的应用,如三维重建、目标定位、导航避障等。
本文主要从宏观上讲述了
双目
成像的各个步骤,从宏观上了解
双目
成像原理,阐述了四大坐标系的相互转化关系。同时也发表了一些自己对
双目
成像原理的感悟以及觉得能够有所改进的地方。
使用长广溪机器人作画需要用到摄像头拍摄人像照片,经过推荐,使用大
恒
相机
,型号为MER-503-36U3C,该
相机
为USB彩色
相机
。提示:以下是本篇文章正文内容,下面案例可供参考。
我们看到红色线条上三个不同远近的黑色的点在下方
相机
上投影在同一个位置,因此单目
相机
无法分辨成的像到底是远的那个还是近的那个。
双目
立体视觉深度
相机
测距流程:(1)需要对
双目
相机
进行
相机
标定,得到两个
相机
的内外参数、单应矩阵。
(2) 根据标定结果对原始图像进行图像校正,校正后的两张图像位于同一平面且互相平行。
(3)
双目
匹配,对校正后的两张图像进行像素点匹配。
(4)根据匹配结果计算每个像素的深度,从而获得深度图
立体标定和立体校正
在利用
双目
图像进行计算视差图和距离的时候,首先要做的步骤就是
双目
的立体标定和立体校正,它是
双目
视觉的基础。立体标定的原因是物体在三维空间中的位置与其在二维图像上的位置之间的关系.
基于以上两个结果,可以用立体矫正后的图像,作为YOLOv8的输入图像。YOLOv8 ONNX RUNTIME 部署代码中的utils.cpp中有一个函数需要作修改。运用SGBM算法得到的视差图,其尺寸与立体矫正后的图像尺寸不一致,如获取深度图代码信息输出图。视差图由SGBM算法获得,深度信息图由reproJectImageTo3D()函数获得。参数6:默认值为0,用户传给回调函数的数据值。参数4:表示滑块达到最大位置的值。参数5:默认值为0,指向回调函数。参数3:滑块初始位置。