【OpenCV】多版本那是interesting

博客主要讨论OpenCV多版本安装使用时的问题。多版本安装时默认安装易冲突,安装ROS会自带OpenCV到默认路径。如配置OpenCV3.2.0和VINS - fusion时运行失败,可链接到ROS自带的4.2.0版本。还介绍了修改报错、找ROS对应OpenCV版本文件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenCV在使用时的问题

摘要

如果多版本安装OpenCV,切勿默认安装,务必每安装一个版本都新建一个目录,这样就会少很多问题。但是安装ROS会不知不觉的将自带的OpenCV安装到默认路径。一样会导致冲突。这时候最好的解决办法还没找到,所以最好的办法就是用ROS自带的OpenCV,虽然有警告,但是可以用呀!

背景

  1. 安装Ubuntu20.04对应的ROS,顺带安装个OpenCV4.2.0安装到默认路径(相当讨厌,也有优势);
  2. 安装了OpenCV4.8.0 到指定目录,用于ORB-SLAM3,顺利使用没有啥问题,未见冲突;
  3. 配置OpenCV3.2.0和VINS-fusion,编译通过,但是显示有警告。最可怕的是运行失败(直接段错误)可以使用gdb调试查看原因,原因是,在链接库文件时它偷偷摸摸链接到OpenCV4.2.0。让人担心的警告直接发生了。可供参考
  4. 解决方法,就是修改找opencv直接链接到ROS自带的4.2.0,编译VINS-fusion通过,但是显示有警告。可是它真的没有偷偷摸摸链接到其他库。勉强可用!!!

关于第3条,警告信息如下,这几个可能conflict

 	/usr/local/opencv3.2.0/lib/libopencv_core.so.3.2
    /usr/local/opencv3.2.0/lib/libopencv_imgcodecs.so.3.2
    /usr/local/opencv3.2.0/lib/libopencv_calib3d.so.3.2
    /usr/lib/x86_64-linux-gnu/libopencv_core.so.4.2
    /usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.4.2
    # /usr/local/opencv3.2.0/lib/libboost_filesystem.so.1.71.0
    /usr/local/opencv3.2.0/lib/libopencv_features2d.so.3.2

关于第4条,警告信息如下:

...
[ 97%] Linking CXX executable /home/pf/VINSfusionFix/devel/lib/vins/kitti_gps_test
[ 98%] Linking CXX executable /home/pf/VINSfusionFix/devel/lib/vins/kitti_odom_test
/usr/bin/ld: warning: libopencv_calib3d.so.4.2, needed by /home/pf/VINSfusionFix/devel/lib/libvins_lib.so, may conflict with libopencv_calib3d.so.3.2
/usr/bin/ld: warning: libopencv_imgcodecs.so.3.2, needed by /home/pf/VINSfusionFix/devel/lib/libvins_lib.so, may conflict with libopencv_imgcodecs.so.4.2
/usr/bin/ld: warning: libopencv_core.so.3.2, needed by /usr/local/opencv3.2.0/lib/libopencv_calib3d.so.3.2, may conflict with libopencv_core.so.4.2
/usr/bin/ld: warning: libopencv_calib3d.so.4.2, needed by /home/pf/VINSfusionFix/devel/lib/libvins_lib.so, may conflict with libopencv_calib3d.so.3.2
/usr/bin/ld: warning: libopencv_imgcodecs.so.3.2, needed by /home/pf/VINSfusionFix/devel/lib/libvins_lib.so, may conflict with libopencv_imgcodecs.so.4.2
/usr/bin/ld: warning: libopencv_core.so.3.2, needed by /usr/local/opencv3.2.0/lib/libopencv_calib3d.so.3.2, may conflict with libopencv_core.so.4.2
[ 98%] Built target kitti_gps_test
[ 98%] Built target kitti_odom_test
[100%] Linking CXX executable /home/pf/VINSfusionFix/devel/lib/vins/vins_node
/usr/bin/ld: warning: libopencv_calib3d.so.4.2, needed by /home/pf/VINSfusionFix/devel/lib/libvins_lib.so, may conflict with libopencv_calib3d.so.3.2
/usr/bin/ld: warning: libopencv_core.so.3.2, needed by /usr/local/opencv3.2.0/lib/libopencv_calib3d.so.3.2, may conflict with libopencv_core.so.4.2
[100%] Built target vins_node

重点解释说明第4条

解决方法,就是修改找opencv直接链接到ROS自带的4.2.0,编译VINS-fusion通过,但是显示有警告。可是它真的没有偷偷摸摸链接到其他库。勉强可用!!!

修改一些报错

ROS noetic版本中的OpenCV4.2和VINS-fusion中需要使用的OpenCV3冲突,修改以兼容OpenCV4。幸运的是发现不用修改代码中不兼容的变量,可以直接添加缺失的头文件即可:

如下

  • 在camera_models包中的头文件Chessboard.h中添加
#include <opencv2/imgproc/types_c.h>
#include <opencv2/calib3d/calib3d_c.h>
  • 在camera_models包中的头文件CameraCalibration.h、pose_graph包中的头文件pose_graph.h和keyframe.h、BRIEF.h中添加
#include <opencv2/imgproc/types_c.h>
#include <opencv2/imgproc/imgproc_c.h>
  • 若vins_estiamtor包中报错,将头文件替换为
// #include <opencv/cv.h>
// #include <opencv/highgui.h>
#include <opencv2/highgui.hpp>
#include <opencv2/cvconfig.h>

找OpenCV

重点是找默认的opencv ,

  • 你以为直接确定版本可以找到ROS对应的4.2.0,可是它找不到
find_package(OpenCV 4.2 REQUIRED)
message(WARNING "OpenCV_VERSION: ${OpenCV_VERSION}")

#输出:
#CMake Warning at CMakeLists.txt:21 (message):
#OpenCV_VERSION: 4.8.0
  • 你以为不加版本直接找可以找到ROS对应的4.2.0,可是它也找不到,不仅找不到,它找上一次有版本的opencv(自己体会这句话)
find_package(OpenCV REQUIRED)
message(WARNING "OpenCV_VERSION: ${OpenCV_VERSION}")

#输出:
#CMake Warning at CMakeLists.txt:21 (message):
#OpenCV_VERSION: 4.8.0
  • 正确的方法 去找ROS对应的4.2.0对应的文件OpenCVConfig.cmake 然后找到路径,这就可以了。
  • cmake编译原理是需要CMakeLists.txt找到 .cmake 文件,就在那几个目录下面,
    1. /usr/share/OpenCV/
    2. /usr/lib/x86_64-linux-gnu/cmake/opencv4/
set(OpenCV_DIR /usr/lib/x86_64-linux-gnu/cmake/opencv4/)
find_package(OpenCV REQUIRED)
# -- Found OpenCV: /usr (found version "4.2.0")
# OPENCV VERSION: 4.2.0
find_package(catkin REQUIRED COMPONENTS
	OpenCV
	)
pf@pf-NUC12WSKi7:~/VINSfusionFix$ catkin_make
Base path: /home/pf/VINSfusionFix
Source space: /home/pf/VINSfusionFix/src
Build space: /home/pf/VINSfusionFix/build
Devel space: /home/pf/VINSfusionFix/devel
Install space: /home/pf/VINSfusionFix/install
####
#### Running command: "make cmake_check_build_system" in "/home/pf/VINSfusionFix/build"
####
####
#### Running command: "make -j16 -l16" in "/home/pf/VINSfusionFix/build"
####
[  5%] Built target libGeographiccc
[ 24%] Built target camera_models
[ 45%] Built target Calibrations
[ 49%] Built target global_fusion_node
[ 68%] Built target loop_fusion_node
[ 91%] Built target vins_lib
[ 97%] Built target kitti_gps_test
[ 97%] Built target kitti_odom_test
[100%] Built target vins_node

首先,让我们分步完成这个任务。我们将使用OpenCV库来处理图像操作,包括读取、转换和区域生长。 1. **读取RGB图像并转换为灰度** ```python import cv2 # 读取图像 image_path = "path_to_your_image.jpg" # 请替换为实际图片路径 rgb_image = cv2.imread(image_path) # 将RGB图像转换为灰度图像 gray_image = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2GRAY) ``` 2. **区域生长算法** 为了实现基于区域生长的分割,我们需要定义相似性阈值(通常用像素值差或颜色直方图差异)。这里我们简单地使用邻域像素的灰度值之差作为相似性准则: ```python def region_growing(gray_image, seed_point, similarity_threshold=5): visited = set([seed_point]) mask = np.zeros_like(gray_image, dtype=np.uint8) mask[tuple(seed_point)] = 255 while len(visited) > 0: current_point = visited.pop() neighbors = [(x, y) for x in range(-1, 2) for y in range(-1, 2) if (0 <= x + current_point[0] < gray_image.shape[0]) and (0 <= y + current_point[1] < gray_image.shape[1])] for neighbor in neighbors: if abs(gray_image[current_point] - gray_image[neighbor]) <= similarity_threshold and mask[neighbor] == 0: visited.add(neighbor) mask[tuple(neighbor)] = 255 return mask # 选择感兴趣的目标内的种子点(例如,可以通过轮廓检测或手动标记) seeds = [tuple(x) for x in get_seeds_from_interesting_regions(gray_image)] # 对每个种子点进行区域生长分割 segmented_masks = {seed: region_growing(gray_image, seed) for seed in seeds} ``` 这里的`get_seeds_from_interesting_regions()`函数需要你自己实现,根据具体需求从感兴趣的区域获取种子点,例如使用轮廓检测(`cv2.findContours()`)或自定义的区域识别方法。 3. **分析相似性阈值的影响** 你可以创建一个循环,遍历多个相似性阈值,并记录每个阈值下的分割结果。例如: ```python thresholds = list(range(1, 50, 5)) # 可以调整范围和步长 results = [] for threshold in thresholds: segmented_mask = region_growing(gray_image, seeds[0], threshold) results.append((threshold, compare_segmentations(segmented_mask, ground_truth))) # 假设ground_truth是实际的分割标签 # 比较分割效果,可能需要用到一些指标如IOU、accuracy等 ``` 4. **多目标分割** 对于多目标分割,只需重复上述步骤,针对每个种子点分别运行区域生长,然后将所有的分割结果合并。这可能涉及到一些额外的逻辑,比如合并重叠的区域或保留最大的连通组件: ```python merged_mask = np.zeros_like(gray_image, dtype=np.uint8) for seed, mask in segmented_masks.items(): merged_mask += merge_overlapping_masks(mask, merged_mask) # 合并后的mask就是多目标分割的结果 ``` 请注意,以上代码提供了基本框架,具体的细节可能需要根据实际图像内容和需求进行调整。如果你需要更详细的帮助,请提供特定的场景或遇到的问题。现在,你可以尝试使用这些代码并根据实际情况调整参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值