mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
commit
afe9993376
@ -1215,3 +1215,16 @@
|
|||||||
year = {1996},
|
year = {1996},
|
||||||
publisher = {Elsevier}
|
publisher = {Elsevier}
|
||||||
}
|
}
|
||||||
|
@Article{Wu2009,
|
||||||
|
author={Wu, Kesheng
|
||||||
|
and Otoo, Ekow
|
||||||
|
and Suzuki, Kenji},
|
||||||
|
title={Optimizing two-pass connected-component labeling algorithms},
|
||||||
|
journal={Pattern Analysis and Applications},
|
||||||
|
year={2009},
|
||||||
|
month={Jun},
|
||||||
|
day={01},
|
||||||
|
volume={12},
|
||||||
|
number={2},
|
||||||
|
pages={117-135},
|
||||||
|
}
|
||||||
|
@ -765,9 +765,14 @@ struct MishFunctor : public BaseFunctor
|
|||||||
{
|
{
|
||||||
// Use fast approximation introduced in https://github.com/opencv/opencv/pull/17200
|
// Use fast approximation introduced in https://github.com/opencv/opencv/pull/17200
|
||||||
float x = srcptr[i];
|
float x = srcptr[i];
|
||||||
float eX = exp(std::min(x, 20.f));
|
if (x >= 8.f)
|
||||||
float n = (eX + 2) * eX;
|
dstptr[i] = x;
|
||||||
dstptr[i] = (x * n) / (n + 2);
|
else
|
||||||
|
{
|
||||||
|
float eX = exp(x);
|
||||||
|
float n = (eX + 2) * eX;
|
||||||
|
dstptr[i] = (x * n) / (n + 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1342,32 +1342,64 @@ void ONNXImporter::populateNet(Net dstNet)
|
|||||||
else if (layer_type == "Gather")
|
else if (layer_type == "Gather")
|
||||||
{
|
{
|
||||||
CV_Assert(node_proto.input_size() == 2);
|
CV_Assert(node_proto.input_size() == 2);
|
||||||
Mat input = getBlob(node_proto, constBlobs, 0);
|
|
||||||
Mat indexMat = getBlob(node_proto, constBlobs, 1);
|
Mat indexMat = getBlob(node_proto, constBlobs, 1);
|
||||||
CV_Assert_N(indexMat.type() == CV_32S, indexMat.total() == 1);
|
CV_Assert_N(indexMat.type() == CV_32S, indexMat.total() == 1);
|
||||||
int index = indexMat.at<int>(0);
|
int index = indexMat.at<int>(0);
|
||||||
|
int axis = layerParams.get<int>("axis", 0);
|
||||||
|
|
||||||
Mat out;
|
if ((constBlobs.find(node_proto.input(0)) != constBlobs.end()))
|
||||||
if (layerParams.has("axis"))
|
|
||||||
{
|
{
|
||||||
int axis = layerParams.get<int>("axis");
|
Mat input = getBlob(node_proto, constBlobs, 0);
|
||||||
|
Mat out;
|
||||||
std::vector<cv::Range> ranges(input.dims, Range::all());
|
std::vector<cv::Range> ranges(input.dims, Range::all());
|
||||||
ranges[axis] = Range(index, index + 1);
|
ranges[axis] = Range(index, index + 1);
|
||||||
|
|
||||||
out = input(ranges);
|
out = input(ranges);
|
||||||
|
MatShape outShape = shape(out);
|
||||||
|
if (outShape.size() > 1)
|
||||||
|
{
|
||||||
|
outShape.erase(outShape.begin() + axis);
|
||||||
|
out.reshape(0, outShape);
|
||||||
|
}
|
||||||
|
addConstant(layerParams.name, out, constBlobs, outShapes);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CV_Assert(index < input.total());
|
shapeIt = outShapes.find(node_proto.input(0));
|
||||||
const int dims = input.dims;
|
CV_Assert(shapeIt != outShapes.end());
|
||||||
input = input.reshape(1, 1);
|
MatShape inpShape = shapeIt->second;
|
||||||
input.dims = 2;
|
|
||||||
out = input.reshape(1, 1).colRange(index, index + 1);
|
LayerParams sliceLp;
|
||||||
out.dims = dims;
|
sliceLp.type = "Slice";
|
||||||
|
sliceLp.name = inpShape.size() > 1 ? layerParams.name + "/slice" : layerParams.name;
|
||||||
|
std::vector<int> begin(inpShape.size(), 0);
|
||||||
|
std::vector<int> end(inpShape.size(), -1);
|
||||||
|
begin[axis] = index;
|
||||||
|
end[axis] = index + 1;
|
||||||
|
|
||||||
|
cv::dnn::DictValue paramBegin = cv::dnn::DictValue::arrayInt(begin.data(), begin.size());
|
||||||
|
cv::dnn::DictValue paramEnd = cv::dnn::DictValue::arrayInt(end.data(), end.size());
|
||||||
|
sliceLp.set("begin", paramBegin);
|
||||||
|
sliceLp.set("end", paramEnd);
|
||||||
|
|
||||||
|
if (inpShape.size() > 1)
|
||||||
|
{
|
||||||
|
opencv_onnx::NodeProto proto;
|
||||||
|
proto.add_input(node_proto.input(0));
|
||||||
|
proto.add_output(sliceLp.name);
|
||||||
|
addLayer(dstNet, sliceLp, proto, layer_id, outShapes);
|
||||||
|
|
||||||
|
inpShape.erase(inpShape.begin() + axis);
|
||||||
|
layerParams.type = "Reshape";
|
||||||
|
layerParams.set("dim", DictValue::arrayInt(&inpShape[0], inpShape.size()));
|
||||||
|
node_proto.set_input(0, sliceLp.name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layerParams = sliceLp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addConstant(layerParams.name, out, constBlobs, outShapes);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else if (layer_type == "Concat")
|
else if (layer_type == "Concat")
|
||||||
{
|
{
|
||||||
|
@ -114,6 +114,17 @@ TEST_P(Test_ONNX_layers, Convolution)
|
|||||||
testONNXModels("convolution");
|
testONNXModels("convolution");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(Test_ONNX_layers, Gather)
|
||||||
|
{
|
||||||
|
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||||
|
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||||
|
testONNXModels("gather");
|
||||||
|
// GPU plugin unsupported slice for constant
|
||||||
|
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||||
|
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||||
|
testONNXModels("gather_scalar", npy, 0, 0, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Test_ONNX_layers, Convolution3D)
|
TEST_P(Test_ONNX_layers, Convolution3D)
|
||||||
{
|
{
|
||||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
|
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
|
||||||
|
@ -401,7 +401,7 @@ enum ConnectedComponentsTypes {
|
|||||||
|
|
||||||
//! connected components algorithm
|
//! connected components algorithm
|
||||||
enum ConnectedComponentsAlgorithmsTypes {
|
enum ConnectedComponentsAlgorithmsTypes {
|
||||||
CCL_WU = 0, //!< SAUF algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
CCL_WU = 0, //!< SAUF @cite Wu2009 algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
||||||
CCL_DEFAULT = -1, //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
CCL_DEFAULT = -1, //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
||||||
CCL_GRANA = 1 //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
CCL_GRANA = 1 //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
||||||
};
|
};
|
||||||
@ -3747,7 +3747,7 @@ image with 4 or 8 way connectivity - returns N, the total number of labels [0, N
|
|||||||
represents the background label. ltype specifies the output label image type, an important
|
represents the background label. ltype specifies the output label image type, an important
|
||||||
consideration based on the total number of labels or alternatively the total number of pixels in
|
consideration based on the total number of labels or alternatively the total number of pixels in
|
||||||
the source image. ccltype specifies the connected components labeling algorithm to use, currently
|
the source image. ccltype specifies the connected components labeling algorithm to use, currently
|
||||||
Grana (BBDT) and Wu's (SAUF) algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes
|
Grana (BBDT) and Wu's (SAUF) @cite Wu2009 algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes
|
||||||
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
|
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
|
||||||
This function uses parallel version of both Grana and Wu's algorithms if at least one allowed
|
This function uses parallel version of both Grana and Wu's algorithms if at least one allowed
|
||||||
parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs.
|
parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs.
|
||||||
@ -3779,7 +3779,7 @@ image with 4 or 8 way connectivity - returns N, the total number of labels [0, N
|
|||||||
represents the background label. ltype specifies the output label image type, an important
|
represents the background label. ltype specifies the output label image type, an important
|
||||||
consideration based on the total number of labels or alternatively the total number of pixels in
|
consideration based on the total number of labels or alternatively the total number of pixels in
|
||||||
the source image. ccltype specifies the connected components labeling algorithm to use, currently
|
the source image. ccltype specifies the connected components labeling algorithm to use, currently
|
||||||
Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes
|
Grana's (BBDT) and Wu's (SAUF) @cite Wu2009 algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes
|
||||||
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
|
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
|
||||||
This function uses parallel version of both Grana and Wu's algorithms (statistics included) if at least one allowed
|
This function uses parallel version of both Grana and Wu's algorithms (statistics included) if at least one allowed
|
||||||
parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs.
|
parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs.
|
||||||
|
@ -178,6 +178,8 @@ enum VideoCaptureProperties {
|
|||||||
CAP_PROP_WB_TEMPERATURE=45, //!< white-balance color temperature
|
CAP_PROP_WB_TEMPERATURE=45, //!< white-balance color temperature
|
||||||
CAP_PROP_CODEC_PIXEL_FORMAT =46, //!< (read-only) codec's pixel format. 4-character code - see VideoWriter::fourcc . Subset of [AV_PIX_FMT_*](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/raw.c) or -1 if unknown
|
CAP_PROP_CODEC_PIXEL_FORMAT =46, //!< (read-only) codec's pixel format. 4-character code - see VideoWriter::fourcc . Subset of [AV_PIX_FMT_*](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/raw.c) or -1 if unknown
|
||||||
CAP_PROP_BITRATE =47, //!< (read-only) Video bitrate in kbits/s
|
CAP_PROP_BITRATE =47, //!< (read-only) Video bitrate in kbits/s
|
||||||
|
CAP_PROP_ORIENTATION_META=48, //!< (read-only) Frame rotation defined by stream meta (applicable for FFmpeg back-end only)
|
||||||
|
CAP_PROP_ORIENTATION_AUTO=49, //!< if true - rotates output frames of CvCapture considering video file's metadata (applicable for FFmpeg back-end only) (https://github.com/opencv/opencv/issues/15499)
|
||||||
#ifndef CV_DOXYGEN
|
#ifndef CV_DOXYGEN
|
||||||
CV__CAP_PROP_LATEST
|
CV__CAP_PROP_LATEST
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,7 +90,11 @@ public:
|
|||||||
if (!ffmpegCapture ||
|
if (!ffmpegCapture ||
|
||||||
!icvRetrieveFrame_FFMPEG_p(ffmpegCapture, &data, &step, &width, &height, &cn))
|
!icvRetrieveFrame_FFMPEG_p(ffmpegCapture, &data, &step, &width, &height, &cn))
|
||||||
return false;
|
return false;
|
||||||
cv::Mat(height, width, CV_MAKETYPE(CV_8U, cn), data, step).copyTo(frame);
|
|
||||||
|
cv::Mat tmp(height, width, CV_MAKETYPE(CV_8U, cn), data, step);
|
||||||
|
this->rotateFrame(tmp);
|
||||||
|
tmp.copyTo(frame);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual bool open( const cv::String& filename )
|
virtual bool open( const cv::String& filename )
|
||||||
@ -113,6 +117,30 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
CvCapture_FFMPEG* ffmpegCapture;
|
CvCapture_FFMPEG* ffmpegCapture;
|
||||||
|
|
||||||
|
void rotateFrame(cv::Mat &mat) const
|
||||||
|
{
|
||||||
|
bool rotation_auto = 0 != getProperty(CAP_PROP_ORIENTATION_AUTO);
|
||||||
|
int rotation_angle = static_cast<int>(getProperty(CAP_PROP_ORIENTATION_META));
|
||||||
|
|
||||||
|
if(!rotation_auto || rotation_angle%360 == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::RotateFlags flag;
|
||||||
|
if(rotation_angle == 90 || rotation_angle == -270) { // Rotate clockwise 90 degrees
|
||||||
|
flag = cv::ROTATE_90_CLOCKWISE;
|
||||||
|
} else if(rotation_angle == 270 || rotation_angle == -90) { // Rotate clockwise 270 degrees
|
||||||
|
flag = cv::ROTATE_90_COUNTERCLOCKWISE;
|
||||||
|
} else if(rotation_angle == 180 || rotation_angle == -180) { // Rotate clockwise 180 degrees
|
||||||
|
flag = cv::ROTATE_180;
|
||||||
|
} else { // Unsupported rotation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::rotate(mat, mat, flag);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -485,6 +485,7 @@ struct CvCapture_FFMPEG
|
|||||||
bool setProperty(int, double);
|
bool setProperty(int, double);
|
||||||
bool grabFrame();
|
bool grabFrame();
|
||||||
bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
|
bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
|
||||||
|
void rotateFrame(cv::Mat &mat) const;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@ -500,6 +501,7 @@ struct CvCapture_FFMPEG
|
|||||||
double r2d(AVRational r) const;
|
double r2d(AVRational r) const;
|
||||||
int64_t dts_to_frame_number(int64_t dts);
|
int64_t dts_to_frame_number(int64_t dts);
|
||||||
double dts_to_sec(int64_t dts) const;
|
double dts_to_sec(int64_t dts) const;
|
||||||
|
void get_rotation_angle();
|
||||||
|
|
||||||
AVFormatContext * ic;
|
AVFormatContext * ic;
|
||||||
AVCodec * avcodec;
|
AVCodec * avcodec;
|
||||||
@ -515,6 +517,8 @@ struct CvCapture_FFMPEG
|
|||||||
|
|
||||||
int64_t frame_number, first_frame_number;
|
int64_t frame_number, first_frame_number;
|
||||||
|
|
||||||
|
bool rotation_auto;
|
||||||
|
int rotation_angle; // valid 0, 90, 180, 270
|
||||||
double eps_zero;
|
double eps_zero;
|
||||||
/*
|
/*
|
||||||
'filename' contains the filename of the videosource,
|
'filename' contains the filename of the videosource,
|
||||||
@ -563,8 +567,17 @@ void CvCapture_FFMPEG::init()
|
|||||||
frame_number = 0;
|
frame_number = 0;
|
||||||
eps_zero = 0.000025;
|
eps_zero = 0.000025;
|
||||||
|
|
||||||
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
|
rotation_angle = 0;
|
||||||
|
|
||||||
|
#if (LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0))
|
||||||
|
#if (LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 92, 100))
|
||||||
|
rotation_auto = true;
|
||||||
|
#else
|
||||||
|
rotation_auto = false;
|
||||||
|
#endif
|
||||||
dict = NULL;
|
dict = NULL;
|
||||||
|
#else
|
||||||
|
rotation_auto = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rawMode = false;
|
rawMode = false;
|
||||||
@ -1033,6 +1046,7 @@ bool CvCapture_FFMPEG::open( const char* _filename )
|
|||||||
frame.cn = 3;
|
frame.cn = 3;
|
||||||
frame.step = 0;
|
frame.step = 0;
|
||||||
frame.data = NULL;
|
frame.data = NULL;
|
||||||
|
get_rotation_angle();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1283,7 +1297,6 @@ bool CvCapture_FFMPEG::grabFrame()
|
|||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
|
bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
|
||||||
{
|
{
|
||||||
if (!video_st)
|
if (!video_st)
|
||||||
@ -1392,9 +1405,9 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
|
|||||||
case CAP_PROP_FRAME_COUNT:
|
case CAP_PROP_FRAME_COUNT:
|
||||||
return (double)get_total_frames();
|
return (double)get_total_frames();
|
||||||
case CAP_PROP_FRAME_WIDTH:
|
case CAP_PROP_FRAME_WIDTH:
|
||||||
return (double)frame.width;
|
return (double)((rotation_auto && rotation_angle%180) ? frame.height : frame.width);
|
||||||
case CAP_PROP_FRAME_HEIGHT:
|
case CAP_PROP_FRAME_HEIGHT:
|
||||||
return (double)frame.height;
|
return (double)((rotation_auto && rotation_angle%180) ? frame.width : frame.height);
|
||||||
case CAP_PROP_FPS:
|
case CAP_PROP_FPS:
|
||||||
return get_fps();
|
return get_fps();
|
||||||
case CAP_PROP_FOURCC:
|
case CAP_PROP_FOURCC:
|
||||||
@ -1438,6 +1451,15 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
|
|||||||
break;
|
break;
|
||||||
case CAP_PROP_BITRATE:
|
case CAP_PROP_BITRATE:
|
||||||
return static_cast<double>(get_bitrate());
|
return static_cast<double>(get_bitrate());
|
||||||
|
case CAP_PROP_ORIENTATION_META:
|
||||||
|
return static_cast<double>(rotation_angle);
|
||||||
|
case CAP_PROP_ORIENTATION_AUTO:
|
||||||
|
#if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \
|
||||||
|
(LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)))
|
||||||
|
return static_cast<double>(rotation_auto);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1516,6 +1538,17 @@ double CvCapture_FFMPEG::dts_to_sec(int64_t dts) const
|
|||||||
r2d(ic->streams[video_stream]->time_base);
|
r2d(ic->streams[video_stream]->time_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CvCapture_FFMPEG::get_rotation_angle()
|
||||||
|
{
|
||||||
|
rotation_angle = 0;
|
||||||
|
#if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \
|
||||||
|
(LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)))
|
||||||
|
AVDictionaryEntry *rotate_tag = av_dict_get(video_st->metadata, "rotate", NULL, 0);
|
||||||
|
if (rotate_tag != NULL)
|
||||||
|
rotation_angle = atoi(rotate_tag->value);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void CvCapture_FFMPEG::seek(int64_t _frame_number)
|
void CvCapture_FFMPEG::seek(int64_t _frame_number)
|
||||||
{
|
{
|
||||||
_frame_number = std::min(_frame_number, get_total_frames());
|
_frame_number = std::min(_frame_number, get_total_frames());
|
||||||
@ -1611,6 +1644,16 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value )
|
|||||||
if (value == -1)
|
if (value == -1)
|
||||||
return setRaw();
|
return setRaw();
|
||||||
return false;
|
return false;
|
||||||
|
case CAP_PROP_ORIENTATION_AUTO:
|
||||||
|
#if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \
|
||||||
|
(LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)))
|
||||||
|
rotation_auto = static_cast<bool>(value);
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
rotation_auto = 0;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -399,4 +399,64 @@ const ffmpeg_cap_properties_param_t videoio_ffmpeg_properties[] = {
|
|||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_cap_properties, testing::ValuesIn(videoio_ffmpeg_properties));
|
INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_cap_properties, testing::ValuesIn(videoio_ffmpeg_properties));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// related issue: https://github.com/opencv/opencv/issues/15499
|
||||||
|
TEST(videoio, mp4_orientation_meta_auto)
|
||||||
|
{
|
||||||
|
if (!videoio_registry::hasBackend(CAP_FFMPEG))
|
||||||
|
throw SkipTestException("FFmpeg backend was not found");
|
||||||
|
|
||||||
|
string video_file = string(cvtest::TS::ptr()->get_data_path()) + "video/big_buck_bunny_rotated.mp4";
|
||||||
|
|
||||||
|
VideoCapture cap;
|
||||||
|
EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG));
|
||||||
|
ASSERT_TRUE(cap.isOpened()) << "Can't open the video: " << video_file << " with backend " << CAP_FFMPEG << std::endl;
|
||||||
|
|
||||||
|
cap.set(CAP_PROP_ORIENTATION_AUTO, true);
|
||||||
|
if (cap.get(CAP_PROP_ORIENTATION_AUTO) == 0)
|
||||||
|
throw SkipTestException("FFmpeg frame rotation metadata is not supported");
|
||||||
|
|
||||||
|
Size actual;
|
||||||
|
EXPECT_NO_THROW(actual = Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
|
||||||
|
(int)cap.get(CAP_PROP_FRAME_HEIGHT)));
|
||||||
|
EXPECT_EQ(384, actual.width);
|
||||||
|
EXPECT_EQ(672, actual.height);
|
||||||
|
|
||||||
|
Mat frame;
|
||||||
|
|
||||||
|
cap >> frame;
|
||||||
|
|
||||||
|
ASSERT_EQ(384, frame.cols);
|
||||||
|
ASSERT_EQ(672, frame.rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
// related issue: https://github.com/opencv/opencv/issues/15499
|
||||||
|
TEST(videoio, mp4_orientation_no_rotation)
|
||||||
|
{
|
||||||
|
if (!videoio_registry::hasBackend(CAP_FFMPEG))
|
||||||
|
throw SkipTestException("FFmpeg backend was not found");
|
||||||
|
|
||||||
|
string video_file = string(cvtest::TS::ptr()->get_data_path()) + "video/big_buck_bunny_rotated.mp4";
|
||||||
|
|
||||||
|
VideoCapture cap;
|
||||||
|
EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG));
|
||||||
|
cap.set(CAP_PROP_ORIENTATION_AUTO, 0);
|
||||||
|
ASSERT_TRUE(cap.isOpened()) << "Can't open the video: " << video_file << " with backend " << CAP_FFMPEG << std::endl;
|
||||||
|
ASSERT_FALSE(cap.get(CAP_PROP_ORIENTATION_AUTO));
|
||||||
|
|
||||||
|
Size actual;
|
||||||
|
EXPECT_NO_THROW(actual = Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
|
||||||
|
(int)cap.get(CAP_PROP_FRAME_HEIGHT)));
|
||||||
|
EXPECT_EQ(672, actual.width);
|
||||||
|
EXPECT_EQ(384, actual.height);
|
||||||
|
|
||||||
|
Mat frame;
|
||||||
|
|
||||||
|
cap >> frame;
|
||||||
|
|
||||||
|
ASSERT_EQ(672, frame.cols);
|
||||||
|
ASSERT_EQ(384, frame.rows);
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
@ -74,9 +74,7 @@ void mouseHandler(int event, int x, int y, int, void*)
|
|||||||
final = Mat::zeros(src.size(), CV_8UC3);
|
final = Mat::zeros(src.size(), CV_8UC3);
|
||||||
mask = Mat::zeros(src.size(), CV_8UC1);
|
mask = Mat::zeros(src.size(), CV_8UC1);
|
||||||
|
|
||||||
vector<vector<Point> > vpts;
|
fillPoly(mask, pts, Scalar(255, 255, 255), 8, 0);
|
||||||
vpts.push_back(pts);
|
|
||||||
fillPoly(mask, vpts, Scalar(255, 255, 255), 8, 0);
|
|
||||||
bitwise_and(src, src, final, mask);
|
bitwise_and(src, src, final, mask);
|
||||||
imshow("Mask", mask);
|
imshow("Mask", mask);
|
||||||
imshow("Result", final);
|
imshow("Result", final);
|
||||||
|
@ -50,9 +50,7 @@ static float drawIntersection(Mat &image, vector<Point> polygon1, vector<Point>
|
|||||||
{
|
{
|
||||||
fillColor = Scalar(0, 0, 255);
|
fillColor = Scalar(0, 0, 255);
|
||||||
}
|
}
|
||||||
vector<vector<Point> > pp;
|
fillPoly(image, intersectionPolygon, fillColor);
|
||||||
pp.push_back(intersectionPolygon);
|
|
||||||
fillPoly(image, pp, fillColor);
|
|
||||||
}
|
}
|
||||||
polylines(image, polygons, true, Scalar(0, 0, 0));
|
polylines(image, polygons, true, Scalar(0, 0, 0));
|
||||||
|
|
||||||
|
@ -121,21 +121,6 @@ static void findSquares( const Mat& image, vector<vector<Point> >& squares )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// the function draws all the squares in the image
|
|
||||||
static void drawSquares( Mat& image, const vector<vector<Point> >& squares )
|
|
||||||
{
|
|
||||||
for( size_t i = 0; i < squares.size(); i++ )
|
|
||||||
{
|
|
||||||
const Point* p = &squares[i][0];
|
|
||||||
int n = (int)squares[i].size();
|
|
||||||
polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, LINE_AA);
|
|
||||||
}
|
|
||||||
|
|
||||||
imshow(wndname, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
static const char* names[] = { "pic1.png", "pic2.png", "pic3.png",
|
static const char* names[] = { "pic1.png", "pic2.png", "pic3.png",
|
||||||
@ -148,8 +133,6 @@ int main(int argc, char** argv)
|
|||||||
names[1] = "0";
|
names[1] = "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<vector<Point> > squares;
|
|
||||||
|
|
||||||
for( int i = 0; names[i] != 0; i++ )
|
for( int i = 0; names[i] != 0; i++ )
|
||||||
{
|
{
|
||||||
string filename = samples::findFile(names[i]);
|
string filename = samples::findFile(names[i]);
|
||||||
@ -160,8 +143,11 @@ int main(int argc, char** argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<vector<Point> > squares;
|
||||||
findSquares(image, squares);
|
findSquares(image, squares);
|
||||||
drawSquares(image, squares);
|
|
||||||
|
polylines(image, squares, true, Scalar(0, 255, 0), 3, LINE_AA);
|
||||||
|
imshow(wndname, image);
|
||||||
|
|
||||||
int c = waitKey();
|
int c = waitKey();
|
||||||
if( c == 27 )
|
if( c == 27 )
|
||||||
|
@ -74,9 +74,9 @@ void load_images( const String & dirname, vector< Mat > & img_lst, bool showImag
|
|||||||
for ( size_t i = 0; i < files.size(); ++i )
|
for ( size_t i = 0; i < files.size(); ++i )
|
||||||
{
|
{
|
||||||
Mat img = imread( files[i] ); // load the image
|
Mat img = imread( files[i] ); // load the image
|
||||||
if ( img.empty() ) // invalid image, skip it.
|
if ( img.empty() )
|
||||||
{
|
{
|
||||||
cout << files[i] << " is invalid!" << endl;
|
cout << files[i] << " is invalid!" << endl; // invalid image, skip it.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,16 +95,13 @@ void sample_neg( const vector< Mat > & full_neg_lst, vector< Mat > & neg_lst, co
|
|||||||
box.width = size.width;
|
box.width = size.width;
|
||||||
box.height = size.height;
|
box.height = size.height;
|
||||||
|
|
||||||
const int size_x = box.width;
|
|
||||||
const int size_y = box.height;
|
|
||||||
|
|
||||||
srand( (unsigned int)time( NULL ) );
|
srand( (unsigned int)time( NULL ) );
|
||||||
|
|
||||||
for ( size_t i = 0; i < full_neg_lst.size(); i++ )
|
for ( size_t i = 0; i < full_neg_lst.size(); i++ )
|
||||||
if ( full_neg_lst[i].cols > box.width && full_neg_lst[i].rows > box.height )
|
if ( full_neg_lst[i].cols > box.width && full_neg_lst[i].rows > box.height )
|
||||||
{
|
{
|
||||||
box.x = rand() % ( full_neg_lst[i].cols - size_x );
|
box.x = rand() % ( full_neg_lst[i].cols - box.width );
|
||||||
box.y = rand() % ( full_neg_lst[i].rows - size_y );
|
box.y = rand() % ( full_neg_lst[i].rows - box.height );
|
||||||
Mat roi = full_neg_lst[i]( box );
|
Mat roi = full_neg_lst[i]( box );
|
||||||
neg_lst.push_back( roi.clone() );
|
neg_lst.push_back( roi.clone() );
|
||||||
}
|
}
|
||||||
@ -259,7 +256,7 @@ int main( int argc, char** argv )
|
|||||||
load_images( pos_dir, pos_lst, visualization );
|
load_images( pos_dir, pos_lst, visualization );
|
||||||
if ( pos_lst.size() > 0 )
|
if ( pos_lst.size() > 0 )
|
||||||
{
|
{
|
||||||
clog << "...[done]" << endl;
|
clog << "...[done] " << pos_lst.size() << " files." << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -287,22 +284,25 @@ int main( int argc, char** argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
clog << "Negative images are being loaded...";
|
clog << "Negative images are being loaded...";
|
||||||
load_images( neg_dir, full_neg_lst, false );
|
load_images( neg_dir, full_neg_lst, visualization );
|
||||||
|
clog << "...[done] " << full_neg_lst.size() << " files." << endl;
|
||||||
|
|
||||||
|
clog << "Negative images are being processed...";
|
||||||
sample_neg( full_neg_lst, neg_lst, pos_image_size );
|
sample_neg( full_neg_lst, neg_lst, pos_image_size );
|
||||||
clog << "...[done]" << endl;
|
clog << "...[done] " << neg_lst.size() << " files." << endl;
|
||||||
|
|
||||||
clog << "Histogram of Gradients are being calculated for positive images...";
|
clog << "Histogram of Gradients are being calculated for positive images...";
|
||||||
computeHOGs( pos_image_size, pos_lst, gradient_lst, flip_samples );
|
computeHOGs( pos_image_size, pos_lst, gradient_lst, flip_samples );
|
||||||
size_t positive_count = gradient_lst.size();
|
size_t positive_count = gradient_lst.size();
|
||||||
labels.assign( positive_count, +1 );
|
labels.assign( positive_count, +1 );
|
||||||
clog << "...[done] ( positive count : " << positive_count << " )" << endl;
|
clog << "...[done] ( positive images count : " << positive_count << " )" << endl;
|
||||||
|
|
||||||
clog << "Histogram of Gradients are being calculated for negative images...";
|
clog << "Histogram of Gradients are being calculated for negative images...";
|
||||||
computeHOGs( pos_image_size, neg_lst, gradient_lst, flip_samples );
|
computeHOGs( pos_image_size, neg_lst, gradient_lst, flip_samples );
|
||||||
size_t negative_count = gradient_lst.size() - positive_count;
|
size_t negative_count = gradient_lst.size() - positive_count;
|
||||||
labels.insert( labels.end(), negative_count, -1 );
|
labels.insert( labels.end(), negative_count, -1 );
|
||||||
CV_Assert( positive_count < labels.size() );
|
CV_Assert( positive_count < labels.size() );
|
||||||
clog << "...[done] ( negative count : " << negative_count << " )" << endl;
|
clog << "...[done] ( negative images count : " << negative_count << " )" << endl;
|
||||||
|
|
||||||
Mat train_data;
|
Mat train_data;
|
||||||
convert_to_ml( gradient_lst, train_data );
|
convert_to_ml( gradient_lst, train_data );
|
||||||
@ -324,7 +324,7 @@ int main( int argc, char** argv )
|
|||||||
|
|
||||||
if ( train_twice )
|
if ( train_twice )
|
||||||
{
|
{
|
||||||
clog << "Testing trained detector on negative images. This may take a few minutes...";
|
clog << "Testing trained detector on negative images. This might take a few minutes...";
|
||||||
HOGDescriptor my_hog;
|
HOGDescriptor my_hog;
|
||||||
my_hog.winSize = pos_image_size;
|
my_hog.winSize = pos_image_size;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user