Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cv.merge causes segmentation fault #120

Closed
TimoReusch opened this issue Jun 27, 2024 · 5 comments
Closed

cv.merge causes segmentation fault #120

TimoReusch opened this issue Jun 27, 2024 · 5 comments
Labels
wontfix This will not be worked on

Comments

@TimoReusch
Copy link

I'm using the following implementation inside of an isolate:

Future<void> processFrame(CameraImage frame) async {
  // Create a ReceivePort for communication with the isolate
  final ReceivePort receivePort = ReceivePort();
  // Spawn the isolate
  await Isolate.spawn(_processFrameIsolate, receivePort.sendPort);
  // Wait for the isolate to send its SendPort
  final SendPort isolateSendPort = await receivePort.first as SendPort;

  // Convert FrameData
  final frameData = {
    'width': frame.width,
    'height': frame.height,
    'format': frame.format.raw,
    'planes': frame.planes
        .map((plane) => {
      'bytes': plane.bytes,
      'bytesPerRow': plane.bytesPerRow,
      'bytesPerPixel': plane.bytesPerPixel,
    })
        .toList(),
  };

  // Create a new ReceivePort for receiving the result
  final ReceivePort resultPort = ReceivePort();

  // Send the frame data along with the result port's SendPort to the isolate
  isolateSendPort.send([frameData, resultPort.sendPort]);

  // Wait for the result from the isolate
  final result = await resultPort.first as Map<String, dynamic>;
  
  // …
}


static void _processFrameIsolate(SendPort sendPort) async {
  print('Isolate spawned');
  // Create a ReceivePort to receive data from the main isolate
  final ReceivePort isolateReceivePort = ReceivePort();
  // Send the isolate's ReceivePort to the main isolate
  sendPort.send(isolateReceivePort.sendPort);

  // Listen for the frame data from the main isolate
  isolateReceivePort.listen((message) async {
    print('Frame data received');
    final frameData = message[0] as Map;
    final SendPort resultPort = message[1] as SendPort;
    // Convert the frame data to a Mat object
    cv.Mat mat = _convertFrameDataToMat(frameData);

    // …
  });
}

static cv.Mat _convertFrameDataToMat(Map frameData) {
  print("Processing frame");
  final int width = frameData['width'];
  final int height = frameData['height'];
  final List planesData = frameData['planes'];

  // Create a Mat for each plane
  List<cv.Mat> planeMats = planesData.map((planeData) {
    final Uint8List bytes = planeData['bytes'];
    cv.Mat mat = cv.Mat.fromList(height, width, cv.MatType.CV_8UC1, bytes);
    return mat;
  }).toList();

  // Create a VecMat from the list of Mats
  cv.VecMat vecMat = cv.VecMat.fromList(planeMats);

  // Merge the plane Mats into a single Mat
  cv.Mat mergedMat = cv.merge(vecMat);

  // Clean up
  planeMats.forEach((mat) => mat?.release());

  return mergedMat;
}

This results in the following error:

F/libc    ( 6969): Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7041940000 in tid 7152 (DartWorker), pid 6969 (my_app)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/taimen/taimen:11/RP1A.201005.004.A1/6934943:user/release-keys'
Revision: 'rev_10'
ABI: 'arm64'
Timestamp: 2024-06-27 14:21:58+0200
pid: 6969, tid: 7152, name: DartWorker  >>> de.timo.my_app <<<
uid: 10190
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7041940000
    x0  0000000000000000  x1  0000006fcf41d010  x2  00000000000e1000  x3  0000000000000003
    x4  0000000000000004  x5  0000000000000000  x6  0000000003000000  x7  0000000000000000
    x8  00000000000e0ff0  x9  0000006fdbf5f040  x10 00000070418cf040  x11 0000000000000000
    x12 0000006fe4dcc040  x13 00000000fffffff0  x14 0000000000070fd0  x15 0000000000070fc0
    x16 0000000000152f40  x17 0000000000000002  x18 0000006fd0420000  x19 00000000000e1000
    x20 0000006fccf5b040  x21 0000006fddb476c8  x22 0000000000000003  x23 0000006fddb49000
    x24 0000000000000003  x25 0000000000000000  x26 0000006fce88d7a0  x27 0000000000000003
    x28 00000000000e1000  x29 0000006fddb47560
    lr  0000006fce88caa8  sp  0000006fddb47540  pc  0000006fce88cbd0  pst 0000000080000000
backtrace:
      #00 pc 0000000000731bd0  /data/app/~~pDchOoXjTxLFXxbRgQsgFw==/de.timo.my_app-60au6JTGgpooivmfe4iyng==/lib/arm64/libopencv_dart.so (BuildId: e85889b8a44465372645f91bcb7f24887cd76169)
      #01 pc 00000000007327f4  /data/app/~~pDchOoXjTxLFXxbRgQsgFw==/de.timo.my_app-60au6JTGgpooivmfe4iyng==/lib/arm64/libopencv_dart.so (BuildId: e85889b8a44465372645f91bcb7f24887cd76169)
      #02 pc 0000000000733048  /data/app/~~pDchOoXjTxLFXxbRgQsgFw==/de.timo.my_app-60au6JTGgpooivmfe4iyng==/lib/arm64/libopencv_dart.so (BuildId: e85889b8a44465372645f91bcb7f24887cd76169)
      #03 pc 0000000000733914  /data/app/~~pDchOoXjTxLFXxbRgQsgFw==/de.timo.my_app-60au6JTGgpooivmfe4iyng==/lib/arm64/libopencv_dart.so (BuildId: e85889b8a44465372645f91bcb7f24887cd76169)
      #04 pc 00000000005e2bd0  /data/app/~~pDchOoXjTxLFXxbRgQsgFw==/de.timo.my_app-60au6JTGgpooivmfe4iyng==/lib/arm64/libopencv_dart.so (Mat_Merge+68) (BuildId: e85889b8a44465372645f91bcb7f24887cd76169)
      #05 pc 0000000000007bc4  [anon:dart-code]

Looks like a segmentation fault to me.

@TimoReusch TimoReusch added the bug Something isn't working label Jun 27, 2024
@rainyl
Copy link
Owner

rainyl commented Jun 27, 2024

Can't reproduce, please provide a minimal example.

@TimoReusch
Copy link
Author

@rainyl I put together a minimal example you can clone and try to run here: https://github.com/TimoReusch/flutter_opencv_merge

@rainyl
Copy link
Owner

rainyl commented Jun 30, 2024

Got it, will try to fix some time, thx~

@rainyl
Copy link
Owner

rainyl commented Jul 1, 2024

Reproduced, but it's not the problem of opencv_dart, the following code worked fine:

  List<cv.Mat> planeMats = planesData.map((planeData) {
    // replace this line
    // final Uint8List bytes = planeData['bytes'];
    // with
    final bytes = List.generate(height * width * 1, (i) => i);
    cv.Mat mat = cv.Mat.fromList(height, width, cv.MatType.CV_8UC1, bytes);
    return mat;
  }).toList();

Thus, I am sure it's because the incorrect use of planeData['bytes'], I haven't used the camera plugin, so do not know what planeData['bytes'] exactly are, if they are encoded image data, please use cv.imdecode to decode, if they are raw pixel values, please ensure the length of planeData['bytes'] is exactly channels*rows*cols, where channels matchs the Mat you created.

I suppose the planeData['bytes'] contains RGB values of an image, then you can't use cv.MatType.CV_8UC1 but cv.MatType.CV_8UC3 should be used, and opencv expects BGR rather than RGB, so look into your code please.

@rainyl rainyl added wontfix This will not be worked on and removed bug Something isn't working cant reproduce labels Jul 1, 2024
@rainyl
Copy link
Owner

rainyl commented Jul 14, 2024

If no further problems, I am going to close this issue.

Feel free to reopen it or open new issues if you still have any problems.

@rainyl rainyl closed this as completed Jul 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants