opencv-python: Segmentation fault using ORB

Expected behaviour

I’m using ORB FE = cv2.ORB_create(self.MAX_FEATURES) as features extractor to do registration.

Actual behaviour

But when I call TargetKP, TargetDesc = FE.detectAndCompute(ImTarget, None), I get a segmentation fault error: Fatal Python error: Segmentation fault.

I have to use the option -X faulthandler to be able to find the line that generates this error, and it the one I mentioned above TargetKP, TargetDesc = FE.detectAndCompute(ImTarget, None), but I just get this line, nothing more, not trace.

Steps to reproduce

  • example code FE = cv2.ORB_create(2013) TargetKP, TargetDesc = FE.detectAndCompute(ImTarget, None)

ImTarget being a 23K x 29K pixels image encoded on 8 bits. For the record, it is dense with information as it is a tissues section, so full of overlapping cells.

  • operating system Linux Centos 7

  • opencv-python version 4.5.1

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 21 (1 by maintainers)

Most upvoted comments

I checked this reproducer with SIFT_create (use opencv 3.4 and master) and got a crash. It looks like there is also an integer overflow error.

OpenCV 4.5.4 is already published in core repository: https://github.com/opencv/opencv/releases/tag/4.5.4. Python packages will be ready in a week or so.

Thank you for your work guys. As you can see in my reproducer code, I tested both ORB and SIFT. I was able to run SIFT with images 35Kx35K, but it’s on a cluster, so lof or memory available.

Problem in HarrisResponses(const Mat& img, const std::vector<Rect>& layerinfo, std::vector<KeyPoint>& pts, int blockSize, float harris_k) from orb.cpp

An integer overflow has occurred in this line: const uchar* ptr0 = ptr00 + (y0 - r + layerinfo[z].y)*step + x0 - r + layerinfo[z].x;

A fix like this fixes the problem:

const uchar* ptr0 = ptr00 + (size_t)(y0 - r + layerinfo[z].y)*(size_t)step + (size_t)x0 - (size_t)r +
                    (size_t)layerinfo[z].x;

I will add a test and open a pull request.

So, here is some code to reproduce it:

import cv2
import numpy as np
from skimage.draw import line_aa

width = 25000 #32760
height = 25000 #32760
image = np.uint8(np.random.randint(0, 50, (height, width)))

border = 23

for i in range(23):
	x1 = np.random.randint(border, width - border)
	x2 = np.random.randint(border, width - border)
	y1 = np.random.randint(border, height - border)
	y2 = np.random.randint(border, height - border)
	rr, cc, val = line_aa(x1, y1, x2, y2)
	image[cc, rr] = val * 255
	image[np.random.randint(border, height - border), np.random.randint(border, width - border)] = 255

target = np.roll(image, 17, axis=0)
target = np.roll(target, 17, axis=1)
print("Images created")
sys.stdout.flush()

fd = cv2.ORB_create(31)
#fd = cv2.SIFT_create(31)

ImageKP, ImageDesc = fd.detectAndCompute(image, None)
print("Features extracted from original image")
sys.stdout.flush()
TargetKP, TargetDesc = fd.detectAndCompute(target, None)
print("Features extracted from target image")
sys.stdout.flush()

It works with SIFT, but not ORB. For ORB, I have to use the option -X faulthandler to get the trace, else I get a simple old segfault. The trace indicates that the faulty command is ImageKP, ImageDesc = fd.detectAndCompute(image, None), so the features extraction with ORB.

Btw, it works with 20Kx20K images, but no longer with 25Kx25. I haven’t narrow it down more than this.

@FiReTiTi do you have any update on the issue? Are you able to reproduce the issue with random generated images?

Not yet, but I’ll try to reproduce it. Donc close it yet.