mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge pull request #28646 from abhishek-gola:kernel_values
Fix kernel shape handling in ONNX importer2 #28646 Requires opencv_extra: https://github.com/opencv/opencv_extra/pull/1323 closes: https://github.com/opencv/opencv/issues/28321 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -1728,6 +1728,15 @@ void simplifySubgraphs(opencv_onnx::GraphProto& net)
|
||||
}
|
||||
|
||||
|
||||
static std::string getExternalDataValue(const opencv_onnx::TensorProto& tensor_proto, const std::string& key)
|
||||
{
|
||||
for (const auto& entry : tensor_proto.external_data())
|
||||
{
|
||||
if (entry.key() == key)
|
||||
return entry.value();
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static char* getTensorRAWData(const opencv_onnx::TensorProto& tensor_proto,
|
||||
std::vector<int64_t>& tensor_data, const std::string& base_path = "")
|
||||
@@ -1735,24 +1744,31 @@ static char* getTensorRAWData(const opencv_onnx::TensorProto& tensor_proto,
|
||||
if (tensor_proto.has_data_location() && tensor_proto.data_location() == opencv_onnx::TensorProto::EXTERNAL) {
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
CV_Assert(tensor_proto.has_data_location() && tensor_proto.data_location() == opencv_onnx::TensorProto::EXTERNAL);
|
||||
auto it_begin = tensor_proto.external_data().begin();
|
||||
auto it_end = tensor_proto.external_data().end();
|
||||
// file path
|
||||
auto it = std::find_if(it_begin, it_end,[](const auto& entry) { return entry.key() == "location"; });
|
||||
CV_CheckTrue(it != it_end, "External tensor data location is not specified");
|
||||
std::string location_path = getExternalDataValue(tensor_proto, "location");
|
||||
CV_CheckTrue(!location_path.empty(), "External tensor data location is not specified");
|
||||
|
||||
|
||||
std::string location_path = it->value();
|
||||
std::string full_path = base_path.empty() ? location_path : utils::fs::join(base_path, location_path);
|
||||
|
||||
std::ifstream file(full_path, std::ios::binary | std::ios::ate);
|
||||
CV_CheckTrue(file.is_open(), "Failed to open external tensor data file");
|
||||
|
||||
size_t size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
tensor_data.resize(divUp((size_t)size, sizeof(int64_t)));
|
||||
size_t file_size = (size_t)file.tellg();
|
||||
size_t offset = 0;
|
||||
std::string offset_str = getExternalDataValue(tensor_proto, "offset");
|
||||
if (!offset_str.empty())
|
||||
offset = (size_t)std::stoull(offset_str);
|
||||
|
||||
file.read((char*)tensor_data.data(), size);
|
||||
size_t length = file_size - offset;
|
||||
std::string length_str = getExternalDataValue(tensor_proto, "length");
|
||||
if (!length_str.empty())
|
||||
length = (size_t)std::stoull(length_str);
|
||||
|
||||
CV_Check(offset, offset <= file_size, "External data offset exceeds file size");
|
||||
CV_Check(length, length <= file_size - offset, "External data length exceeds available bytes");
|
||||
|
||||
file.seekg(offset, std::ios::beg);
|
||||
tensor_data.resize(divUp(length, sizeof(int64_t)));
|
||||
file.read((char*)tensor_data.data(), length);
|
||||
return (char*)tensor_data.data();
|
||||
#else
|
||||
CV_Error(Error::StsNotImplemented, "External tensor data is not supported without filesystem support");
|
||||
|
||||
@@ -1370,7 +1370,7 @@ void ONNXImporter2::parseConv(LayerParams& layerParams, const opencv_onnx::NodeP
|
||||
int n_inputs = node_proto.input_size();
|
||||
CV_Assert(2 <= n_inputs && n_inputs <= 3);
|
||||
layerParams.type = "Conv2";
|
||||
addLayer(layerParams, node_proto);
|
||||
addLayer(layerParams, node_proto, n_inputs);
|
||||
}
|
||||
|
||||
void ONNXImporter2::parseConvTranspose(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
|
||||
|
||||
@@ -2563,6 +2563,12 @@ TEST_P(Test_ONNX_nets, MobileNet_v2_FP16)
|
||||
testONNXModels("mobilenetv2_fp16", npy, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, MobileNet_v4)
|
||||
{
|
||||
required = true;
|
||||
testONNXModels("mobilenetv4", npy, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, LResNet100E_IR)
|
||||
{
|
||||
applyTestTag(
|
||||
|
||||
Reference in New Issue
Block a user