|
|
@ -8,6 +8,7 @@
|
|
|
|
#include "GPIOControl.h"
|
|
|
|
#include "GPIOControl.h"
|
|
|
|
#include "CvText.h"
|
|
|
|
#include "CvText.h"
|
|
|
|
#include "PositionHelper.h"
|
|
|
|
#include "PositionHelper.h"
|
|
|
|
|
|
|
|
#include "DngCreator.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
#include <opencv2/core.hpp>
|
|
|
|
#include <opencv2/core.hpp>
|
|
|
@ -21,6 +22,7 @@
|
|
|
|
#include <android/thermal.h>
|
|
|
|
#include <android/thermal.h>
|
|
|
|
#include <android/imagedecoder.h>
|
|
|
|
#include <android/imagedecoder.h>
|
|
|
|
#include <sys/system_properties.h>
|
|
|
|
#include <sys/system_properties.h>
|
|
|
|
|
|
|
|
#include <media/NdkImage.h>
|
|
|
|
#include <mat.h>
|
|
|
|
#include <mat.h>
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USING_HDRPLUS
|
|
|
|
#ifdef USING_HDRPLUS
|
|
|
@ -29,6 +31,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <filesystem>
|
|
|
|
#include <filesystem>
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
|
|
|
|
|
|
|
|
#define CMD_SET_485_EN_STATE 131
|
|
|
|
#define CMD_SET_485_EN_STATE 131
|
|
|
@ -159,7 +162,7 @@ static inline uint32_t YUV2RGB(int nY, int nU, int nV) {
|
|
|
|
return 0xff000000 | (nR << 16) | (nG << 8) | nB;
|
|
|
|
return 0xff000000 | (nR << 16) | (nG << 8) | nB;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CPhoneDevice::CPhoneCamera::CPhoneCamera(CPhoneDevice* dev, int32_t width, int32_t height, const NdkCamera::CAMERA_PARAMS& params, int burstCaptures) : NdkCamera(width, height, params, burstCaptures), m_dev(dev)
|
|
|
|
CPhoneDevice::CPhoneCamera::CPhoneCamera(CPhoneDevice* dev, int32_t width, int32_t height, const NdkCamera::CAMERA_PARAMS& params) : NdkCamera(width, height, params), m_dev(dev)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -178,9 +181,13 @@ bool CPhoneDevice::CPhoneCamera::on_image(cv::Mat& rgb)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CPhoneDevice::CPhoneCamera::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, const std::vector<std::shared_ptr<ACameraMetadata> >& results, const std::vector<std::shared_ptr<AImage> >& frames)
|
|
|
|
bool CPhoneDevice::CPhoneCamera::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, std::vector<std::shared_ptr<AImage> >& frames)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
if (m_dev != NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return m_dev->onBurstCapture(characteristics, results, ldr, frames);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CPhoneDevice::CPhoneCamera::on_error(const std::string& msg)
|
|
|
|
void CPhoneDevice::CPhoneCamera::on_error(const std::string& msg)
|
|
|
@ -204,8 +211,12 @@ CPhoneDevice::CJpegCamera::CJpegCamera(CPhoneDevice* dev, int32_t width, int32_t
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CPhoneDevice::CJpegCamera::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, const std::vector<std::shared_ptr<ACameraMetadata> >& results, const std::vector<std::shared_ptr<AImage> >& frames)
|
|
|
|
bool CPhoneDevice::CJpegCamera::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, std::vector<std::shared_ptr<AImage> >& frames)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (m_dev != NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
m_dev->onBurstCapture(characteristics, results, ldr, frames);
|
|
|
|
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -242,8 +253,7 @@ void CPhoneDevice::CJpegCamera::onImageAvailable(AImageReader* reader)
|
|
|
|
uint64_t avgY = std::accumulate(y_data, y_data + y_len, 0);
|
|
|
|
uint64_t avgY = std::accumulate(y_data, y_data + y_len, 0);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
avgY = avgY / (uint64_t)y_len;
|
|
|
|
avgY = avgY / (uint64_t)y_len;
|
|
|
|
mResult.avgY = avgY;
|
|
|
|
mLdr = avgY;
|
|
|
|
mFinalResult.avgY = avgY;
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
#if 1
|
|
|
|
if (avgY < 50)
|
|
|
|
if (avgY < 50)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -268,10 +278,6 @@ void CPhoneDevice::CJpegCamera::onImageAvailable(AImageReader* reader)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_INFO, "Photo Taken: AES=%u AFS=%u AWBS=%u", (uint32_t)mFinalResult.aeState, (uint32_t)mFinalResult.awbState, (uint32_t)mFinalResult.afState);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mFinalResult.duration = GetMicroTimeStamp() - m_startTime;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t format;
|
|
|
|
int32_t format;
|
|
|
|
AImage_getFormat(image, &format);
|
|
|
|
AImage_getFormat(image, &format);
|
|
|
|
|
|
|
|
|
|
|
@ -1337,6 +1343,8 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector<
|
|
|
|
params.requestTemplate = mPhotoInfo.requestTemplate;
|
|
|
|
params.requestTemplate = mPhotoInfo.requestTemplate;
|
|
|
|
params.awbMode = mPhotoInfo.awbMode;
|
|
|
|
params.awbMode = mPhotoInfo.awbMode;
|
|
|
|
params.wait3ALocked = mPhotoInfo.wait3ALocked;
|
|
|
|
params.wait3ALocked = mPhotoInfo.wait3ALocked;
|
|
|
|
|
|
|
|
params.burstRawCapture = mPhotoInfo.usingRawFormat;
|
|
|
|
|
|
|
|
params.burstCaptures = mPhotoInfo.burstCaptures;
|
|
|
|
if (params.requestTemplate <= 0 || params.requestTemplate > 5)
|
|
|
|
if (params.requestTemplate <= 0 || params.requestTemplate > 5)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
params.requestTemplate = 2;
|
|
|
|
params.requestTemplate = 2;
|
|
|
@ -1363,7 +1371,7 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector<
|
|
|
|
TurnOnCameraPower(NULL);
|
|
|
|
TurnOnCameraPower(NULL);
|
|
|
|
|
|
|
|
|
|
|
|
res = true;
|
|
|
|
res = true;
|
|
|
|
if (mPhotoInfo.mediaType == 0 && mPhotoInfo.usingRawFormat == 0)
|
|
|
|
if (mPhotoInfo.mediaType == 0/* && mPhotoInfo.usingRawFormat == 0*/)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mCamera = new CPhoneCamera(this, photoInfo.width, photoInfo.height, params);
|
|
|
|
mCamera = new CPhoneCamera(this, photoInfo.width, photoInfo.height, params);
|
|
|
|
// mCamera = new CJpegCamera(this, photoInfo.width, photoInfo.height, mPath, params);
|
|
|
|
// mCamera = new CJpegCamera(this, photoInfo.width, photoInfo.height, mPath, params);
|
|
|
@ -1507,6 +1515,330 @@ void DrawOutlineText(cv::Ptr<cv::ft::FreeType2> ft2, cv::Mat& mat, const std::st
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CPhoneDevice::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, std::vector<std::shared_ptr<AImage> >& frames)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
time_t takingTime = time(NULL);
|
|
|
|
|
|
|
|
if (mPhotoInfo.remedy != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if ((takingTime - mPhotoInfo.scheduleTime) > 30)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
takingTime = mPhotoInfo.scheduleTime + mPhotoInfo.channel * 2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mPhotoInfo.photoTime = takingTime;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<IDevice::OSD_INFO> osds;
|
|
|
|
|
|
|
|
osds.swap(mOsds);
|
|
|
|
|
|
|
|
PHOTO_INFO photoInfo = mPhotoInfo;
|
|
|
|
|
|
|
|
std::string path;
|
|
|
|
|
|
|
|
path.swap(mPath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string tmpPath = m_appPath + (APP_DIR_TMP DIR_SEP_STR) + std::to_string(photoInfo.photoId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT;
|
|
|
|
|
|
|
|
ACameraMetadata_const_entry e = { 0 };
|
|
|
|
|
|
|
|
camera_status_t status = ACameraMetadata_getConstEntry(characteristics.get(), ACAMERA_LENS_FACING, &e);
|
|
|
|
|
|
|
|
if (status == ACAMERA_OK)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int sensorOrientation = 0;
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ACameraMetadata_const_entry e = { 0 };
|
|
|
|
|
|
|
|
status = ACameraMetadata_getConstEntry(characteristics.get(), ACAMERA_SENSOR_ORIENTATION, &e);
|
|
|
|
|
|
|
|
if (status == ACAMERA_OK)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sensorOrientation = (int)e.data.i32[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool turnOffOtg = (photoInfo.usbCamera != 0);
|
|
|
|
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
|
|
|
|
mCamera = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::thread th([=]
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Mat rgb;
|
|
|
|
|
|
|
|
std::vector<std::vector<uint8_t> > rawFiles;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
media_status_t mstatus;
|
|
|
|
|
|
|
|
std::string cameraInfo;
|
|
|
|
|
|
|
|
if (photoInfo.usingRawFormat != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
for (int idx = 0; idx < frames.size(); idx++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::shared_ptr<AImage> spImage = frames[idx];
|
|
|
|
|
|
|
|
std::shared_ptr<ACameraMetadata> result = results[idx];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto it = rawFiles.insert(rawFiles.end(), std::vector<uint8_t>());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t width;
|
|
|
|
|
|
|
|
int32_t height;
|
|
|
|
|
|
|
|
AImage_getWidth(spImage.get(), &width);
|
|
|
|
|
|
|
|
AImage_getHeight(spImage.get(), &height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int planeCount;
|
|
|
|
|
|
|
|
media_status_t status = AImage_getNumberOfPlanes(spImage.get(), &planeCount);
|
|
|
|
|
|
|
|
AASSERT(status == AMEDIA_OK && planeCount == 1, "Error: getNumberOfPlanes() planeCount = %d", planeCount);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t *data = nullptr;
|
|
|
|
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
mstatus = AImage_getPlaneData(spImage.get(), 0, &data, &len);
|
|
|
|
|
|
|
|
DngCreator dngCreator(characteristics.get(), result.get());
|
|
|
|
|
|
|
|
dngCreator.writeInputBuffer(*it, data, len, width, height, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (results.size() == 1 && frames.size() == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::shared_ptr<ACameraMetadata> result = results[0];
|
|
|
|
|
|
|
|
std::shared_ptr<AImage> frame = frames[0];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (photoInfo.outputDbgInfo != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
NdkCamera::CAPTURE_RESULT captureResult = { 0 };
|
|
|
|
|
|
|
|
NdkCamera::EnumCameraResult(result.get(), captureResult);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char extimeunit[4] = { 0 };
|
|
|
|
|
|
|
|
unsigned int extime = (captureResult.exposureTime >= 1000000) ? ((unsigned int)(captureResult.exposureTime / 1000000)) : ((unsigned int)(captureResult.exposureTime / 1000));
|
|
|
|
|
|
|
|
strcpy(extimeunit, (captureResult.exposureTime >= 1000000) ? "ms" : "μs");
|
|
|
|
|
|
|
|
char str[128] = { 0 };
|
|
|
|
|
|
|
|
snprintf(str, sizeof(str), "AE=%u AF=%u EXPS=%u%s(%d) ISO=%d AFS=%u AES=%u AWBS=%u SCENE=%d LDR=%d(%u) %0.1fx T=%u FD=%lld",
|
|
|
|
|
|
|
|
captureResult.autoExposure, captureResult.autoFocus,
|
|
|
|
|
|
|
|
extime, extimeunit, captureResult.compensation, captureResult.sensitivity,
|
|
|
|
|
|
|
|
// isnan(captureResult.FocusDistance) ? 0 : captureResult.FocusDistance,
|
|
|
|
|
|
|
|
(unsigned int)captureResult.afState, (unsigned int)captureResult.aeState, captureResult.awbState,
|
|
|
|
|
|
|
|
captureResult.sceneMode, GpioControl::getLightAdc(), ldr, captureResult.zoomRatio,
|
|
|
|
|
|
|
|
(uint32_t)captureResult.duration, captureResult.frameDuration);
|
|
|
|
|
|
|
|
cameraInfo = str;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t format;
|
|
|
|
|
|
|
|
media_status_t mstatus = AImage_getFormat(frame.get(), &format);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (format == AIMAGE_FORMAT_YUV_420_888)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int32_t width;
|
|
|
|
|
|
|
|
int32_t height;
|
|
|
|
|
|
|
|
mstatus = AImage_getWidth(frame.get(), &width);
|
|
|
|
|
|
|
|
mstatus = AImage_getHeight(frame.get(), &height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t y_pixelStride = 0;
|
|
|
|
|
|
|
|
int32_t u_pixelStride = 0;
|
|
|
|
|
|
|
|
int32_t v_pixelStride = 0;
|
|
|
|
|
|
|
|
AImage_getPlanePixelStride(frame.get(), 0, &y_pixelStride);
|
|
|
|
|
|
|
|
AImage_getPlanePixelStride(frame.get(), 1, &u_pixelStride);
|
|
|
|
|
|
|
|
AImage_getPlanePixelStride(frame.get(), 2, &v_pixelStride);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t y_rowStride = 0;
|
|
|
|
|
|
|
|
int32_t u_rowStride = 0;
|
|
|
|
|
|
|
|
int32_t v_rowStride = 0;
|
|
|
|
|
|
|
|
AImage_getPlaneRowStride(frame.get(), 0, &y_rowStride);
|
|
|
|
|
|
|
|
AImage_getPlaneRowStride(frame.get(), 1, &u_rowStride);
|
|
|
|
|
|
|
|
AImage_getPlaneRowStride(frame.get(), 2, &v_rowStride);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t* y_data = 0;
|
|
|
|
|
|
|
|
uint8_t* u_data = 0;
|
|
|
|
|
|
|
|
uint8_t* v_data = 0;
|
|
|
|
|
|
|
|
int y_len = 0;
|
|
|
|
|
|
|
|
int u_len = 0;
|
|
|
|
|
|
|
|
int v_len = 0;
|
|
|
|
|
|
|
|
AImage_getPlaneData(frame.get(), 0, &y_data, &y_len);
|
|
|
|
|
|
|
|
AImage_getPlaneData(frame.get(), 1, &u_data, &u_len);
|
|
|
|
|
|
|
|
AImage_getPlaneData(frame.get(), 2, &v_data, &v_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// already nv21
|
|
|
|
|
|
|
|
ConvertYUV21ToMat(y_data, width, height, photoInfo.width, photoInfo.height, sensorOrientation, facing == ACAMERA_LENS_FACING_FRONT, photoInfo.orientation, rgb);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// construct nv21
|
|
|
|
|
|
|
|
uint8_t* nv21 = new uint8_t[width * height + width * height / 2];
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Y
|
|
|
|
|
|
|
|
uint8_t* yptr = nv21;
|
|
|
|
|
|
|
|
for (int y = 0; y < height; y++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const uint8_t* y_data_ptr = y_data + y_rowStride * y;
|
|
|
|
|
|
|
|
for (int x = 0; x < width; x++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
yptr[0] = y_data_ptr[0];
|
|
|
|
|
|
|
|
yptr++;
|
|
|
|
|
|
|
|
y_data_ptr += y_pixelStride;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// UV
|
|
|
|
|
|
|
|
uint8_t* uvptr = nv21 + width * height;
|
|
|
|
|
|
|
|
for (int y = 0; y < height / 2; y++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const uint8_t* v_data_ptr = v_data + v_rowStride * y;
|
|
|
|
|
|
|
|
const uint8_t* u_data_ptr = u_data + u_rowStride * y;
|
|
|
|
|
|
|
|
for (int x = 0; x < width / 2; x++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uvptr[0] = v_data_ptr[0];
|
|
|
|
|
|
|
|
uvptr[1] = u_data_ptr[0];
|
|
|
|
|
|
|
|
uvptr += 2;
|
|
|
|
|
|
|
|
v_data_ptr += v_pixelStride;
|
|
|
|
|
|
|
|
u_data_ptr += u_pixelStride;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConvertYUV21ToMat(nv21, width, height, photoInfo.width, photoInfo.height, sensorOrientation, facing == ACAMERA_LENS_FACING_FRONT, photoInfo.orientation, rgb);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delete[] nv21;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (photoInfo.outputDbgInfo != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, photoInfo.photoId, turnOffOtg);
|
|
|
|
|
|
|
|
m_threadClose.swap(closeThread);
|
|
|
|
|
|
|
|
if (closeThread.joinable())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
closeThread.detach();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef OUTPUT_CAMERA_DBG_INFO
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
bool shouldRetry = false;
|
|
|
|
|
|
|
|
if (ldr != ~0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (ldr < MIN_LIGHT_Y)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (photoInfo.retries < (DEFAULT_TAKE_PHOTO_RETRIES - 1))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
shouldRetry = true;
|
|
|
|
|
|
|
|
char presetBuf[16] = {0};
|
|
|
|
|
|
|
|
snprintf(presetBuf, sizeof(presetBuf), "%02X", photoInfo.retries);
|
|
|
|
|
|
|
|
// replaceAll(fullPath, ".jpg", std::string("-") + std::to_string(photoInfo.retries) + ".jpg");
|
|
|
|
|
|
|
|
replaceAll(fullPath, "_FF_", std::string("_") + presetBuf + std::string("_"));
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_ERROR, "Photo is TOO dark or light(LDR=%u), will RETRY it",
|
|
|
|
|
|
|
|
(uint32_t) captureResult.avgY);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// photoInfo.usingRawFormat = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (ldr > MAX_LIGHT_Y)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (photoInfo.retries < (DEFAULT_TAKE_PHOTO_RETRIES - 1))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
shouldRetry = true;
|
|
|
|
|
|
|
|
char presetBuf[16] = {0};
|
|
|
|
|
|
|
|
snprintf(presetBuf, sizeof(presetBuf), "%02X", photoInfo.retries);
|
|
|
|
|
|
|
|
// replaceAll(fullPath, ".jpg", std::string("-") + std::to_string(photoInfo.retries) + ".jpg");
|
|
|
|
|
|
|
|
replaceAll(fullPath, "_FF_", std::string("_") + presetBuf + std::string("_"));
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_ERROR, "Photo is TOO dark or light(LDR=%u), will RETRY it",
|
|
|
|
|
|
|
|
(uint32_t) captureResult.avgY);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
photoInfo.compensation = -2 * ((int16_t) ((uint16_t) captureResult.avgY));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // 0
|
|
|
|
|
|
|
|
#endif // OUTPUT_CAMERA_DBG_INFO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Notify to take next photo
|
|
|
|
|
|
|
|
TakePhotoCb(1, photoInfo, "", takingTime);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (photoInfo.usingRawFormat != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::vector<std::string> rawFilePaths;
|
|
|
|
|
|
|
|
for (auto it = rawFiles.cbegin(); it != rawFiles.cend(); ++it)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::string dngFilePath = tmpPath + std::to_string(std::distance(rawFiles.cbegin(), it)) + ".dng";
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
|
|
char log[256] = { 0 };
|
|
|
|
|
|
|
|
strcpy(log, dngFilePath.c_str());
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
FILE *file = fopen(dngFilePath.c_str(), "wb");
|
|
|
|
|
|
|
|
if (file) {
|
|
|
|
|
|
|
|
if (!(*it).empty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fwrite(&((*it)[0]), 1, (*it).size(), file);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(file);
|
|
|
|
|
|
|
|
rawFilePaths.push_back(dngFilePath);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_ERROR, "Start HDR CH=%u IMGID=%u", (uint32_t)mPhotoInfo.channel, (uint32_t)mPhotoInfo.photoId);
|
|
|
|
|
|
|
|
hdrplus::hdrplus_pipeline pipeline;
|
|
|
|
|
|
|
|
pipeline.run_pipeline(rawFilePaths, 0, rgb);
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_ERROR, "Finish HDR CH=%u IMGID=%u", (uint32_t)mPhotoInfo.channel, (uint32_t)mPhotoInfo.photoId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef NDEBUG
|
|
|
|
|
|
|
|
for (auto it = rawFilePaths.cbegin(); it != rawFiles.cend(); ++it)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::remove((*it).c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Mat tempPic = convert16bit2_8bit_(rgb);
|
|
|
|
|
|
|
|
rgb = tempPic;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (photoInfo.orientation > 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (photoInfo.orientation == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (facing == ACAMERA_LENS_FACING_FRONT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::flip(rgb, rgb, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (photoInfo.orientation == 2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Mat tempPic;
|
|
|
|
|
|
|
|
cv::transpose(rgb, tempPic);
|
|
|
|
|
|
|
|
cv::flip(tempPic, rgb, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (photoInfo.orientation == 3)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (facing == ACAMERA_LENS_FACING_FRONT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
flip(rgb, rgb, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::flip(rgb, rgb, -1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (photoInfo.orientation == 4)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Mat tempPic;
|
|
|
|
|
|
|
|
cv::transpose(rgb, tempPic);
|
|
|
|
|
|
|
|
cv::flip(tempPic, rgb, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_ERROR, "Finish rotation CH=%u IMGID=%u", (uint32_t)photoInfo.channel, (uint32_t)photoInfo.photoId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cv::cvtColor(rgb, rgb, cv::COLOR_RGB2BGR);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool res = PostProcessPhoto(photoInfo, osds, path, cameraInfo, rgb);
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// TakePhotoCb(2, photoInfo, path, takingTime);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
th.detach();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CPhoneDevice::OnImageReady(cv::Mat& mat)
|
|
|
|
bool CPhoneDevice::OnImageReady(cv::Mat& mat)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
time_t takingTime = time(NULL);
|
|
|
|
time_t takingTime = time(NULL);
|
|
|
@ -1662,24 +1994,13 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat)
|
|
|
|
|
|
|
|
|
|
|
|
if (mCamera != NULL)
|
|
|
|
if (mCamera != NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
NdkCamera::CAPTURE_RESULT captureResult = mCamera->getCaptureResult();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mPhotoInfo.outputDbgInfo != 0)
|
|
|
|
if (mPhotoInfo.outputDbgInfo != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cv::Scalar scalarRed(0, 0, 255); // red
|
|
|
|
cv::Scalar scalarRed(0, 0, 255); // red
|
|
|
|
|
|
|
|
|
|
|
|
char extimeunit[4] = { 0 };
|
|
|
|
char extimeunit[4] = { 0 };
|
|
|
|
unsigned int extime = (captureResult.exposureTime >= 1000000) ? ((unsigned int)(captureResult.exposureTime / 1000000)) : ((unsigned int)(captureResult.exposureTime / 1000));
|
|
|
|
|
|
|
|
strcpy(extimeunit, (captureResult.exposureTime >= 1000000) ? "ms" : "μs");
|
|
|
|
|
|
|
|
char str[128] = { 0 };
|
|
|
|
char str[128] = { 0 };
|
|
|
|
snprintf(str, sizeof(str), "AE=%u AF=%u EXPS=%u%s(%d) ISO=%d AFS=%u AES=%u AWBS=%u SCENE=%d LDR=%d(%u) %0.1fx T=%u FD=%lld",
|
|
|
|
|
|
|
|
captureResult.autoExposure, captureResult.autoFocus,
|
|
|
|
|
|
|
|
extime, extimeunit, captureResult.compensation, captureResult.sensitivity,
|
|
|
|
|
|
|
|
// isnan(captureResult.FocusDistance) ? 0 : captureResult.FocusDistance,
|
|
|
|
|
|
|
|
(unsigned int)captureResult.afState, (unsigned int)captureResult.aeState, captureResult.awbState,
|
|
|
|
|
|
|
|
captureResult.sceneMode, GpioControl::getLightAdc(), (unsigned int)captureResult.avgY, captureResult.zoomRatio,
|
|
|
|
|
|
|
|
(uint32_t)captureResult.duration, captureResult.frameDuration);
|
|
|
|
|
|
|
|
// cv::putText(mat, str, cv::Point(0, mat.rows - 20), cv::FONT_HERSHEY_COMPLEX, fontScale, scalarWhite, thickness1, cv::LINE_AA);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int fs = fontSize * 2 / 3;
|
|
|
|
int fs = fontSize * 2 / 3;
|
|
|
|
textSize = ft2->getTextSize(str, fs, -1, &baseline);
|
|
|
|
textSize = ft2->getTextSize(str, fs, -1, &baseline);
|
|
|
@ -1811,29 +2132,255 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat)
|
|
|
|
#ifdef OUTPUT_CAMERA_DBG_INFO
|
|
|
|
#ifdef OUTPUT_CAMERA_DBG_INFO
|
|
|
|
if (shouldRetry)
|
|
|
|
if (shouldRetry)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TakePhotoCb(false, mPhotoInfo, fullPath, takingTime, objs);
|
|
|
|
TakePhotoCb(0, mPhotoInfo, fullPath, takingTime, objs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TakePhotoCb(res, mPhotoInfo, fullPath, takingTime, objs);
|
|
|
|
TakePhotoCb(res ? 3 : 0, mPhotoInfo, fullPath, takingTime, objs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
TakePhotoCb(res, mPhotoInfo, fullPath, takingTime, objs);
|
|
|
|
TakePhotoCb(res ? 3 : 0, mPhotoInfo, fullPath, takingTime, objs);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ALOGI("Photo file exists: %s", mPath.c_str());
|
|
|
|
ALOGI("Photo file exists: %s", mPath.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
|
|
|
|
mCamera = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
return res;
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
|
}
|
|
|
|
m_threadClose.swap(closeThread);
|
|
|
|
|
|
|
|
if (closeThread.joinable())
|
|
|
|
bool CPhoneDevice::PostProcessPhoto(const PHOTO_INFO& photoInfo, const vector<IDevice::OSD_INFO>& osds, const std::string& path, const std::string& cameraInfo, cv::Mat& mat)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
closeThread.detach();
|
|
|
|
int baseline = 0;
|
|
|
|
|
|
|
|
cv::Size textSize;
|
|
|
|
|
|
|
|
double height = mat.rows;
|
|
|
|
|
|
|
|
double width = mat.cols;
|
|
|
|
|
|
|
|
// double ratio = std::min(height / 1024, width / 1920);
|
|
|
|
|
|
|
|
double ratio = height / 1024.0;
|
|
|
|
|
|
|
|
int thickness = round(1.4 * ratio);
|
|
|
|
|
|
|
|
if (thickness < 1) thickness = 1;
|
|
|
|
|
|
|
|
else if (thickness > 5) thickness = 5;
|
|
|
|
|
|
|
|
cv::Scalar scalarWhite(255, 255, 255); // white
|
|
|
|
|
|
|
|
int fontSize = (int)(28.0 * ratio);
|
|
|
|
|
|
|
|
cv::Point pt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string fontPath;
|
|
|
|
|
|
|
|
if (existsFile("/system/fonts/NotoSansCJK-Regular.ttc"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fontPath = "/system/fonts/NotoSansCJK-Regular.ttc";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (existsFile("/system/fonts/NotoSerifCJK-Regular.ttc"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fontPath = "/system/fonts/NotoSerifCJK-Regular.ttc";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fontPath = m_appPath+ "fonts/Noto.otf";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cv::Ptr<cv::ft::FreeType2> ft2;
|
|
|
|
|
|
|
|
ft2 = cv::ft::createFreeType2();
|
|
|
|
|
|
|
|
ft2->loadFontData(fontPath.c_str(), 0);
|
|
|
|
|
|
|
|
// cv::Rect rc(0, 0, mat.cols, mat.rows);
|
|
|
|
|
|
|
|
// cv::rectangle (mat, rc, cv::Scalar(255, 255, 255), cv::FILLED);
|
|
|
|
|
|
|
|
std::vector<IDevice::RECOG_OBJECT> objs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((m_pRecognizationCfg != NULL) && (m_pRecognizationCfg->enabled != 0) && (photoInfo.recognization != 0))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_INFO, "Channel AI Enabled");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// visualize(ncnnPath.c_str(), in);
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
|
|
double startTime = ncnn::get_current_time();
|
|
|
|
|
|
|
|
#endif // _DEBUG
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool detected = YoloV5NcnnDetect(mat, true, m_pRecognizationCfg->blobName8, m_pRecognizationCfg->blobName16, m_pRecognizationCfg->blobName32, objs);
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
|
|
double elasped = ncnn::get_current_time() - startTime;
|
|
|
|
|
|
|
|
// __android_log_print(ANDROID_LOG_DEBUG, "YoloV5Ncnn", "%.2fms detect", elasped);
|
|
|
|
|
|
|
|
#endif // _DEBUG
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
|
|
ALOGI( "NCNN recognization: %.2fms res=%d", elasped, ((detected && !objs.empty()) ? 1 : 0));
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (detected && !objs.empty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Scalar borderColor(m_pRecognizationCfg->borderColor & 0xFF, (m_pRecognizationCfg->borderColor & 0xFF00) >> 8, (m_pRecognizationCfg->borderColor & 0xFF0000) >> 16);
|
|
|
|
|
|
|
|
cv::Scalar textColor(m_pRecognizationCfg->textColor & 0xFF, (m_pRecognizationCfg->textColor & 0xFF00) >> 8, (m_pRecognizationCfg->textColor & 0xFF0000) >> 16);
|
|
|
|
|
|
|
|
float minSizeW = m_pRecognizationCfg->minSize > 0 ? (photoInfo.width * m_pRecognizationCfg->minSize / 100) : 0;
|
|
|
|
|
|
|
|
float minSizeH = m_pRecognizationCfg->minSize > 0 ? (photoInfo.height * m_pRecognizationCfg->minSize / 100) : 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (std::vector<IDevice::RECOG_OBJECT>::const_iterator it = objs.cbegin(); it != objs.cend();)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (it->label >= m_pRecognizationCfg->items.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
it = objs.erase(it);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const IDevice::CFG_RECOGNIZATION::ITEM& item = m_pRecognizationCfg->items[it->label];
|
|
|
|
|
|
|
|
if (item.enabled == 0 || it->prob < item.prob)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
it = objs.erase(it);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_pRecognizationCfg->minSize > 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (it->w < minSizeW || it->h < minSizeH)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
it = objs.erase(it);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((photoInfo.recognization & 0x2) != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Rect rc(it->x, it->y, it->w, it->h);
|
|
|
|
|
|
|
|
cv::rectangle(mat, rc, borderColor, m_pRecognizationCfg->thickness);
|
|
|
|
|
|
|
|
textSize = ft2->getTextSize(item.name, fontSize, thickness, &baseline);
|
|
|
|
|
|
|
|
textSize.height += baseline;
|
|
|
|
|
|
|
|
if (it->y > textSize.height)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.y = it->y - textSize.height - 4 - m_pRecognizationCfg->thickness;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (mat.rows - it->y - it->h > textSize.height)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.y = it->y + it->h + 4 + m_pRecognizationCfg->thickness;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Inner
|
|
|
|
|
|
|
|
pt.y = it->y + 4 + m_pRecognizationCfg->thickness;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mat.cols - it->x > textSize.width)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.x = it->x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.x = it->x + it->w - textSize.width;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef OUTPUT_CAMERA_DBG_INFO
|
|
|
|
|
|
|
|
char buf[128];
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "AI: %d=%s (%f,%f)-(%f,%f) Text:(%d,%d)-(%d,%d)",
|
|
|
|
|
|
|
|
it->label, item.name.c_str(), it->x, it->y, it->w, it->h, pt.x, pt.y, textSize.width, textSize.height);
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_DEBUG, buf);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ft2->putText(mat, item.name + std::to_string((int)(it->prob * 100.0)) + "%", pt, fontSize, textColor, thickness, cv::LINE_AA, false, true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
++it;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_WARNING, "Channel AI Disabled");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef OUTPUT_CAMERA_DBG_INFO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!cameraInfo.empty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// NdkCamera::CAPTURE_RESULT captureResult = mCamera->getCaptureResult();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (photoInfo.outputDbgInfo != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Scalar scalarRed(0, 0, 255); // red
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int fs = fontSize * 2 / 3;
|
|
|
|
|
|
|
|
textSize = ft2->getTextSize(cameraInfo, fs, -1, &baseline);
|
|
|
|
|
|
|
|
cv::Point lt(0, mat.rows - fs - 20 * ratio);
|
|
|
|
|
|
|
|
cv::Point lt2(0, lt.y - 2 * ratio);
|
|
|
|
|
|
|
|
cv::Point rb(0 + textSize.width + 2 * ratio, lt2.y + textSize.height + 8 * ratio);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (rb.x > (int)width - 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rb.x = (int)width - 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rb.y > (int)height - 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rb.y = (int)height - 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cv::Mat roi = mat(cv::Rect(lt2, rb));
|
|
|
|
|
|
|
|
cv::Mat clrMat(roi.size(), CV_8UC3, scalarWhite);
|
|
|
|
|
|
|
|
double alpha = 0.5;
|
|
|
|
|
|
|
|
cv::addWeighted(clrMat, alpha, roi, 1.0 - alpha, 0.0, roi);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cv::rectangle(mat, lt2, rb,cv::Scalar(255, 255, 255), -1);
|
|
|
|
|
|
|
|
ft2->putText(mat, cameraInfo, lt, fs, scalarRed, -1, cv::LINE_AA, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DrawOutlineText(ft2, mat, str, cv::Point(0, mat.rows - fs - 20 * ratio), fs, scalarWhite, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// #endif // OUTPUT_CAMERA_DBG_INFO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (vector<OSD_INFO>::const_iterator it = osds.cbegin(); it != osds.cend(); ++it)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (it->text.empty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
|
|
if (it->alignment == OSD_ALIGNMENT_BOTTOM_RIGHT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int aa = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
textSize = ft2->getTextSize(it->text, fontSize, thickness, &baseline);
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_DEBUG, "%s font Size=%d height: %d baseline=%d", it->text.c_str(), fontSize, textSize.height, baseline);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (it->alignment == OSD_ALIGNMENT_TOP_LEFT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.x = it->x * ratio;
|
|
|
|
|
|
|
|
pt.y = it->y * ratio;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (it->alignment == OSD_ALIGNMENT_TOP_RIGHT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.x = width - textSize.width - it->x * ratio;
|
|
|
|
|
|
|
|
pt.y= it->y * ratio;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (it->alignment == OSD_ALIGNMENT_BOTTOM_RIGHT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.x = width - textSize.width - it->x * ratio;
|
|
|
|
|
|
|
|
pt.y = height - it->y * ratio - textSize.height - baseline;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (it->alignment == OSD_ALIGNMENT_BOTTOM_LEFT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pt.x = it->x * ratio;
|
|
|
|
|
|
|
|
pt.y = height - it->y * ratio - textSize.height - baseline;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cv::Rect rc(pt.x, pt.y, textSize.width, textSize.height);
|
|
|
|
|
|
|
|
// cv::rectangle(mat, rc, cv::Scalar(0,255,255), 2);
|
|
|
|
|
|
|
|
DrawOutlineText(ft2, mat, it->text, pt, fontSize, scalarWhite, thickness);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<int> params;
|
|
|
|
|
|
|
|
params.push_back(cv::IMWRITE_JPEG_QUALITY);
|
|
|
|
|
|
|
|
params.push_back((int)((uint32_t)photoInfo.quality));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool res = false;
|
|
|
|
|
|
|
|
std::string fullPath = endsWith(path, ".jpg") ? path : (path + CTerminal::BuildPhotoFileName(photoInfo));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(std::filesystem::path(fullPath)))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
bool res = cv::imwrite(fullPath.c_str(), mat, params);
|
|
|
|
|
|
|
|
if (!res)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_ERROR, "Failed to Write File: %s", fullPath.c_str() + m_appPath.size());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_INFO, "Succeeded to Write File: %s", fullPath.c_str() + m_appPath.size());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TakePhotoCb(res ? 2 : 0, photoInfo, fullPath, photoInfo.photoTime, objs);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XYLOG(XYLOG_SEVERITY_INFO, "Photo File Exists: %s", fullPath.c_str() + m_appPath.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
@ -1851,7 +2398,7 @@ bool CPhoneDevice::OnCaptureReady(bool photoOrVideo, bool result, cv::Mat& mat,
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::vector<IDevice::RECOG_OBJECT> objs;
|
|
|
|
std::vector<IDevice::RECOG_OBJECT> objs;
|
|
|
|
TakePhotoCb(result, mPhotoInfo, "", time(NULL), objs);
|
|
|
|
TakePhotoCb(0, mPhotoInfo, "", time(NULL), objs);
|
|
|
|
|
|
|
|
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
mCamera = NULL;
|
|
|
|
mCamera = NULL;
|
|
|
@ -1885,7 +2432,7 @@ bool CPhoneDevice::OnVideoReady(bool photoOrVideo, bool result, const char* path
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::rename(path, fullPath.c_str());
|
|
|
|
std::rename(path, fullPath.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TakePhotoCb(result, mPhotoInfo, fullPath, time(NULL), objs);
|
|
|
|
TakePhotoCb(result ? 3 : 0, mPhotoInfo, fullPath, time(NULL), objs);
|
|
|
|
|
|
|
|
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
@ -1907,7 +2454,7 @@ void CPhoneDevice::onError(const std::string& msg)
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
mCamera = NULL;
|
|
|
|
mCamera = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
TakePhotoCb(false, mPhotoInfo, mPath, 0);
|
|
|
|
TakePhotoCb(0, mPhotoInfo, mPath, 0);
|
|
|
|
|
|
|
|
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
@ -1926,7 +2473,7 @@ void CPhoneDevice::onDisconnected(ACameraDevice* device)
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
CPhoneCamera* pCamera = mCamera;
|
|
|
|
mCamera = NULL;
|
|
|
|
mCamera = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
TakePhotoCb(false, mPhotoInfo, mPath, 0);
|
|
|
|
TakePhotoCb(0, mPhotoInfo, mPath, 0);
|
|
|
|
|
|
|
|
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
bool turnOffOtg = (mPhotoInfo.usbCamera != 0);
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
|
std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg);
|
|
|
@ -2157,6 +2704,7 @@ int CPhoneDevice::GetWData(IDevice::WEATHER_INFO *weatherInfo)
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USING_N938
|
|
|
|
#ifdef USING_N938
|
|
|
|
bool CPhoneDevice::OpenSensors()
|
|
|
|
bool CPhoneDevice::OpenSensors()
|
|
|
|
{
|
|
|
|
{
|
|
|
|