opencv像素值索引越界导致异常的问题

最近在写一个点云投影到相机平面的程序,我设置了一个Mask, 然后物体分割出的部分像素值设置成物体的id,其余为0。但是在运行过程中发现有些点的像素值大于39,例如153,255等。但是物体id最大为39。我是用指针的方法查询像素值的。

//u v 是点云投影到像素平面的横纵坐标
// mask 
cv::Vec3b color = mask.ptr<cv::Vec3b>(v)[u];
int color_1 = color[0]

这里不得不提一下opencv像素索引的规则了,无论是用指针的方式,还是at的方式,都是y,x。
在 OpenCV 中,.at() 和 .ptr() 都是获取像素值的函数。在使用这些函数时,第一个参数是纵坐标,第二个参数是横坐标。例如,在 C++ 中,uchar value = img.at(y,x) 中,y 代表纵坐标,x 代表横坐标,ptr(y)[x]。y纵坐标,即行数,x横坐标,即列数。一般用u表示横坐标,v表示纵坐标。
我一开始以为指针有越界报错,所以像素值出现异常的时候没有怀疑是越界的问题。后来打印出来像素值异常的像素点的横纵坐标,发现v的坐标比cols大,但是程序并没有越界报错。后来自己写了一段程序测试了一下。代码如下:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui_c.h>
#include<iostream>

int main(){
    cv::Mat img = cv::Mat::ones(500,1000,CV_8UC3);
    int u = 1001;//u 比 cols大
    int v = 523;// v 比cols大
    cv::Vec3b color_tmp1 = img.ptr<cv::Vec3b>(v)[u];
    int B = color_tmp1[0];
    int G = color_tmp1[1];
    int R = color_tmp1[2];
    cv::Vec3b color_tmp2 = img.at<cv::Vec3b>(v,u);
    int B_2 = color_tmp2[0];
    int G_2 = color_tmp2[1];
    int R_2 = color_tmp2[2];
    std::cout<<"B G R is ::"<<B<<" "<<G<<" "<<R<<std::endl; 
    std::cout<<"B_2 G_2 R_2 is ::"<<B_2<<" "<<G_2<<" "<<R_2<<std::endl;
    return 0;
}

运行结果如下:

B G R is ::95 95 101
B_2 G_2 R_2 is ::95 95 101

将u的值改为负数:

int main(){
    cv::Mat img = cv::Mat::ones(500,1000,CV_8UC3);
    int u = -5;
    int v = 523;
    cv::Vec3b color_tmp1 = img.ptr<cv::Vec3b>(v)[u];
    int B = color_tmp1[0];
    int G = color_tmp1[1];
    int R = color_tmp1[2];
    cv::Vec3b color_tmp2 = img.at<cv::Vec3b>(v,u);
    int B_2 = color_tmp2[0];
    int G_2 = color_tmp2[1];
    int R_2 = color_tmp2[2];
    std::cout<<"B G R is ::"<<B<<" "<<G<<" "<<R<<std::endl; 
    std::cout<<"B_2 G_2 R_2 is ::"<<B_2<<" "<<G_2<<" "<<R_2<<std::endl;
    return 0;
}

运行结果如下:

B G R is ::84 77 67
B_2 G_2 R_2 is ::84 77 67

把v的值改为负数:

int main(){
    cv::Mat img = cv::Mat::ones(500,1000,CV_8UC3);
    int u = 500;
    int v = -5;
    cv::Vec3b color_tmp1 = img.ptr<cv::Vec3b>(v)[u];
    int B = color_tmp1[0];
    int G = color_tmp1[1];
    int R = color_tmp1[2];
    cv::Vec3b color_tmp2 = img.at<cv::Vec3b>(v,u);
    int B_2 = color_tmp2[0];
    int G_2 = color_tmp2[1];
    int R_2 = color_tmp2[2];
    std::cout<<"B G R is ::"<<B<<" "<<G<<" "<<R<<std::endl; 
    std::cout<<"B_2 G_2 R_2 is ::"<<B_2<<" "<<G_2<<" "<<R_2<<std::endl;
    return 0;
}

运行结果:

段错误 (核心已转储)

当索引像素值时,只有当y为负数时,才会越界报错, y比行数大的时候,不会报错只会出现错误像素值。x是正负都不会报错,但是可能会导致像素值异常。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值