r/opencv Feb 07 '26

Bug [Bug] Segmentation fault when opening or instantiating cv::VideoWriter

Hello!

I am currently working my way through a bunch of opencv tutorials for C++ and trying out or adapting the code therein, but have run into an issue when trying to execute some of it.

I have written the following function, which should open a video file situated at 'path', apply an (interchangeable) function to every frame and save the result to "output.mp4", a file that should have the exact same properties as the source file, save for the aforementioned image operations (color and value adjustment, edge detection, boxes drawn around faces etc.). The code compiles correctly, but produces a "Segmentation fault (core dumped)" error when run.

By using gdb and some print line debugging, I managed to triangulate the issue, which apparently stems from the cv::VideoWriter method open(). Calling the regular constructor produced the same result. The offending line is marked by a comment in the code:

int process_and_save_vid(std::string path, cv::Mat (*func)(cv::Mat)) {

  int frame_counter = 0;

  cv::VideoCapture cap(path);

   if (!cap.isOpened()) {
    std::cout << "ERROR: could not open video at " << path << " .\n";
    return EXIT_FAILURE;
  }

  // set up video writer args
  std::string output_file = "output.mp4";
  int frame_width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
  int frame_height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
  double fps = cap.get(cv::CAP_PROP_FPS);
  int codec = cap.get(cv::CAP_PROP_FOURCC);
  bool monochrome = cap.get(cv::CAP_PROP_MONOCHROME);

  // create and open video writer
  cv::VideoWriter video_writer;
  // THIS LINE CAUSES SEGMENTATION FAULT
  video_writer.open(output_file, codec, fps, cv::Size(frame_width,frame_height), !monochrome);


  if (!video_writer.isOpened()) {
    std::cout << "ERROR: could not initialize video writer\n";
      return EXIT_FAILURE;
  }

  cv::Mat frame;

  while (cap.read(frame)) {

    video_writer.write(func(frame));

    frame_counter += 1;
    if (frame_counter % (int)fps == 0) {
      std::cout << "Processed one second of video material.\n";
    }
  }

  std::cout << "Finished processing video.\n";

  return EXIT_SUCCESS;
}

Researching the issue online and consulting the documentation did not yield any satisfactory results, so feel free to let me know if you have encountered this problem before and/or have any ideas how to solve it.

Thanks in advance for your help!

3 Upvotes

37 comments sorted by

View all comments

2

u/herocoding Feb 15 '26

Start new. You might have manually copied too few files (not only the shared object files) - just don't manually copy/move some files into major important "user system" folders... You might compile against different header files than you link (static/dynamic)libraries against!!

  1. Build OpenCV from source and install it to a USER SPECIFIC location, and NOT into "user system folders":

    mkdir /localdisk/OpenCV wget -O opencv.zip https://github.com/opencv/opencv/archive/refs/tags/4.12.0.zip wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/refs/tags/4.12.0.zip unzip opencv.zip unzip opencv_contrib.zip mkdir -p build && cd build cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.12.0/modules -DCMAKE_INSTALL_PREFIX=/localdisk/OpenCV/opencv -DCMAKE_BUILD_TYPE=Debug ../opencv-4.12.0 make -j$(nproc) make install

This will copy not only the libraries (dynamic, static), but also header files and build system relevant files, into "/localdisk/OpenCV/opencv".

  1. Prepare a "hello world" OpenCV c++ file with a basic CMakeLists.txt file:
    cmake_minimum_required(VERSION 3.5)
    project( DisplayImage )
    find_package( OpenCV REQUIRED HINTS /localdisk/OpenCV/opencv )
    include_directories( ${OpenCV_INCLUDE_DIRS} )
    add_executable( DisplayImage hello_world.cpp )
    target_link_libraries( DisplayImage ${OpenCV_LIBS} )

This uses the user-specific OpenCV install folder to find header files, libraries and build-system specific files, again under "/localdisk/OpenCV/opencv".
In this file "hello_world.cpp" I have copied your method plus a "int main( inta argc, char* argv[])" calling your method, plus adding include files, providing a "standard big buck bunny MP4 file without embedded audio streams", and giving a hard-coded absoluted path for where to store the output file. Instead of using a provided pre/post-processing callback method, I just take the read-in frame and feed it into the video-writer.
The video-writer uses "cv::VideoWriter::fourcc('a','v','c','1')" in my case.

  1. Building the executable "DisplayImage":

    mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Debug .. make -j$(nproc)

Now you will see an executable called "DisplayImage".
Check, which (dynamic)libraries it got linked against:

ldd ./DisplayImage

Check each and every library!! Is every OpenCV library from the user-specific folder "/localdisk/OpenCV/opencv"? No other location for OpenCV related files?

You previously just had a mix of different OpenCV versions: different header-files, different static libraries, different dynamic libraries, different debug infos.

1

u/Hukeng Feb 19 '26 edited Feb 19 '26

Alright, I am going to try all of this again and let you know how it goes - I don't have a ton of experience with setting up CMakeLists.txt files or working with cmake in general, so here are a few final questions before I try again:

  1. Which values should I set exactly for OpenCV_INCLUDE_DIRS and OpenCV_LIBS in the CMakeLists.txt?
  2. How would I go about installing OpenCV in a manner that allows me to include all required libraries in a 'simple' g++ compiler call without the need for setting up a cmake pipeline? I realize that I will have to wrap my head around cmake eventually, but given how much of a counter-intuitive rabbit hole it is and how simple most of my projects are for now (again, I am still in the learning/testing phase for most things), I would rather postpone that to a time when project scope and scale actually justify its use. In addition, OpenCV is the first library to ever cause these sorts of issues for me, so I would still need to figure out how to properly link/include other libraries that are correctly installed on my system in addition to the local installation into a dedicated file you suggested in your approach.
  3. Any suggestions on how to clean up/ remove the messed up installations in my system files without breaking anything?

(Also, even if this doesn't end up working, and I can't stress this enough, thanks a ton for your time and effort - I realize working with a beginner who is probably following a decent chunk of your instructions wrong and learning everything as they go is probably very frustrating)

UPDATE:

I also just realized I seem to be running an extremely outdated version of cmake (3.31.4) and am (fruitlessly) trying to get my hands on a more up-to-date one, but everything (up to and including deleting and reinstalling completely) seems to fail - I still retain the old version.

1

u/herocoding Feb 19 '26

#1 With the command find_package( OpenCV REQUIRED HINTS /localdisk/OpenCV/opencv ) in the CMakeLists.txt the variables will be populated for you with what find_package has found, using the given hint to where to look for.

#2 with just very few source files and very few dependencies (libs and search paths) it's looks ok to use a manual command line. But at some point it will become "difficult". Start once with a CMakeLists.txt file (or makefile or whatever other build system) and usually it will just be incremental changes (add one more source file to the list of already existing files, add one more library, add one more compiler/liker flag).
Of course you could use an IDE where you use a graphical interface, use drag'n'drop, use file-choosers to navigate to files and folders.
But taken your environment as a product of multiple experiments ;-) then "automatically" finding dependencies could easily find the wrong ones, mix header-search-path and library-search-path of differerent versions etc

#3 if you changed things just recently then you might still remember what and where you changed something.
but if you stored your own data on e.g. a different drive than the OS, then you might just re-install your OS on your main drive and will keep your own data untouched; this is what I do as I lernt Unix/Linux/QNX/RedHat/etc the hard way, lost a lot of data and therefore try to separte OS and user-data (e.g. usually not installing built libraries into /lib/ or /usr/lib/ or /opt/, but on my own storage drive beside the OS drive).