1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge pull request #28678 from omrope79:caffe-importer-cleanup

Caffe importer cleanup #28678

Merge with: https://github.com/opencv/opencv_extra/pull/1324

### 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
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
omrope79
2026-06-02 19:58:10 +05:30
committed by GitHub
parent 42fc6939f8
commit b67ad9a422
34 changed files with 327 additions and 5674 deletions
+22 -122
View File
@@ -82,6 +82,13 @@ class dnn_test(NewOpenCVTests):
g_dnnBackendsAndTargets = self.initBackendsAndTargets()
self.dnnBackendsAndTargets = g_dnnBackendsAndTargets
def checkIETarget(self, backend, target):
# OpenVINO is optional; a target is usable only if its backend lists it.
try:
return target in cv.dnn.getAvailableTargets(backend)
except BaseException:
return False
def initBackendsAndTargets(self):
self.dnnBackendsAndTargets = [
[cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_CPU],
@@ -109,20 +116,6 @@ class dnn_test(NewOpenCVTests):
os.environ['OPENCV_TEST_DATA_PATH']],
required=required)
def checkIETarget(self, backend, target):
proto = self.find_dnn_file('dnn/layers/layer_convolution.prototxt')
model = self.find_dnn_file('dnn/layers/layer_convolution.caffemodel')
net = cv.dnn.readNet(proto, model, engine=cv.dnn.ENGINE_CLASSIC)
try:
net.setPreferableBackend(backend)
net.setPreferableTarget(target)
inp = np.random.standard_normal([1, 2, 10, 11]).astype(np.float32)
net.setInput(inp)
net.forward()
except BaseException:
return False
return True
def test_getAvailableTargets(self):
targets = cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_OPENCV)
self.assertTrue(cv.dnn.DNN_TARGET_CPU in targets)
@@ -219,25 +212,24 @@ class dnn_test(NewOpenCVTests):
def test_model(self):
img_path = self.find_dnn_file("dnn/street.png")
weights = self.find_dnn_file("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", required=False)
config = self.find_dnn_file("dnn/MobileNetSSD_deploy_19e3ec3.prototxt", required=False)
if weights is None or config is None:
raise unittest.SkipTest("Missing DNN test files (dnn/MobileNetSSD_deploy_19e3ec3.{prototxt/caffemodel}). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
weights = self.find_dnn_file("dnn/onnx/models/ssd_vgg16.onnx", required=False)
if weights is None:
raise unittest.SkipTest("Missing DNN test files (dnn/onnx/models/ssd_vgg16.onnx). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
frame = cv.imread(img_path)
model = cv.dnn_DetectionModel(weights, config)
model.setInputParams(size=(300, 300), mean=(127.5, 127.5, 127.5), scale=1.0/127.5)
model = cv.dnn_DetectionModel(weights)
model.setInputParams(size=(300, 300), mean=(0, 0, 0), scale=1.0, swapRB=False)
iouDiff = 0.05
confThreshold = 0.0001
confThreshold = 0.3
nmsThreshold = 0
scoreDiff = 1.1e-3
scoreDiff = 5e-3
classIds, confidences, boxes = model.detect(frame, confThreshold, nmsThreshold)
refClassIds = (7, 15)
refConfidences = (0.9998, 0.8793)
refBoxes = ((328, 238, 85, 102), (101, 188, 34, 138))
refClassIds = (37,)
refConfidences = (0.8196,)
refBoxes = ((331, 233, 85, 107),)
normAssertDetections(self, refClassIds, refConfidences, refBoxes,
classIds, confidences, boxes,confThreshold, scoreDiff, iouDiff)
@@ -251,14 +243,13 @@ class dnn_test(NewOpenCVTests):
def test_classification_model(self):
img_path = self.find_dnn_file("dnn/googlenet_0.png")
weights = self.find_dnn_file("dnn/squeezenet_v1.1.caffemodel", required=False)
config = self.find_dnn_file("dnn/squeezenet_v1.1.prototxt")
weights = self.find_dnn_file("dnn/squeezenet_v1.1.onnx", required=False)
ref = np.load(self.find_dnn_file("dnn/squeezenet_v1.1_prob.npy"))
if weights is None or config is None:
raise unittest.SkipTest("Missing DNN test files (dnn/squeezenet_v1.1.{prototxt/caffemodel}). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
if weights is None:
raise unittest.SkipTest("Missing DNN test files (dnn/squeezenet_v1.1.onnx). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
frame = cv.imread(img_path)
model = cv.dnn_ClassificationModel(config, weights)
model = cv.dnn_ClassificationModel(weights)
model.setInputSize(227, 227)
model.setInputCrop(True)
@@ -323,54 +314,6 @@ class dnn_test(NewOpenCVTests):
normAssertDetections(self, refClassIds, refScores, refBoxes, testClassIds,
testScores, testBoxes, 0.5)
def test_async(self):
# bug: https://github.com/opencv/opencv/issues/26376
raise unittest.SkipTest("The new dnn engine does not support async inference")
timeout = 10*1000*10**6 # in nanoseconds (10 sec)
proto = self.find_dnn_file('dnn/layers/layer_convolution.prototxt')
model = self.find_dnn_file('dnn/layers/layer_convolution.caffemodel')
if proto is None or model is None:
raise unittest.SkipTest("Missing DNN test files (dnn/layers/layer_convolution.{prototxt/caffemodel}). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
print('\n')
for backend, target in self.dnnBackendsAndTargets:
if backend != cv.dnn.DNN_BACKEND_INFERENCE_ENGINE:
continue
printParams(backend, target)
netSync = cv.dnn.readNet(proto, model, engine=cv.dnn.ENGINE_CLASSIC)
netSync.setPreferableBackend(backend)
netSync.setPreferableTarget(target)
netAsync = cv.dnn.readNet(proto, model)
netAsync.setPreferableBackend(backend)
netAsync.setPreferableTarget(target)
# Generate inputs
numInputs = 10
inputs = []
for _ in range(numInputs):
inputs.append(np.random.standard_normal([2, 6, 75, 113]).astype(np.float32))
# Run synchronously
refs = []
for i in range(numInputs):
netSync.setInput(inputs[i])
refs.append(netSync.forward())
# Run asynchronously. To make test more robust, process inputs in the reversed order.
outs = []
for i in reversed(range(numInputs)):
netAsync.setInput(inputs[i])
outs.insert(0, netAsync.forwardAsync())
for i in reversed(range(numInputs)):
ret, result = outs[i].get(timeoutNs=float(timeout))
self.assertTrue(ret)
normAssert(self, refs[i], result, 'Index: %d' % i, 1e-10)
def test_nms(self):
confs = (1, 1)
rects = ((0, 0, 0.4, 0.4), (0, 0, 0.2, 0.4)) # 0.5 overlap
@@ -401,51 +344,8 @@ class dnn_test(NewOpenCVTests):
return [inputs[0][:,:,self.ystart:self.yend,self.xstart:self.xend]]
cv.dnn_registerLayer('CropCaffe', CropLayer)
proto = '''
name: "TestCrop"
input: "input"
input_shape
{
dim: 1
dim: 2
dim: 5
dim: 5
}
input: "roi"
input_shape
{
dim: 1
dim: 2
dim: 3
dim: 3
}
layer {
name: "Crop"
type: "CropCaffe"
bottom: "input"
bottom: "roi"
top: "Crop"
}'''
net = cv.dnn.readNetFromCaffe(bytearray(proto.encode()))
for backend, target in self.dnnBackendsAndTargets:
if backend != cv.dnn.DNN_BACKEND_OPENCV:
continue
printParams(backend, target)
net.setPreferableBackend(backend)
net.setPreferableTarget(target)
src_shape = [1, 2, 5, 5]
dst_shape = [1, 2, 3, 3]
inp = np.arange(0, np.prod(src_shape), dtype=np.float32).reshape(src_shape)
roi = np.empty(dst_shape, dtype=np.float32)
net.setInput(inp, "input")
net.setInput(roi, "roi")
out = net.forward()
ref = inp[:, :, 1:4, 1:4]
normAssert(self, out, ref)
# Skipped: Requires ONNX custom layer multi-input support and Python binding fixes for Net.connect (see #26200).
cv.dnn_unregisterLayer('CropCaffe')
# check that dnn module can work with 3D tensor as input for network