【问题标题】:A Memory Error by Using OpenCV使用 OpenCV 的内存错误
【发布时间】:2016-12-12 12:33:22
【问题描述】:

照片在这里:

当我单击鼠标左键和 [CTRL] 按钮时,我想看到这个绿色的白人。

代码看起来是点击点的 8 个相邻点并进行递归。 该代码在小矩阵中正常工作。但在这张照片中,我得到了一个内存错误。我想见那个穿绿衣的人。如何正确修复代码?

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int n=0;
void yap(int i,int j,Mat* res){
ostringstream t;
Mat *rgb=(Mat*) res;
Mat res1;
res1=*rgb;
t<<"fark_binary"<<n<<".jpg";
    imwrite(t.str(),res1);
if(res1.at<Vec3b>(i,j)[0]>=200){
    cout<<j<<"\n"<<i;
    res1.at<Vec3b>(i,j)[0]=0;
    res1.at<Vec3b>(i,j)[1]=255;
    res1.at<Vec3b>(i,j)[2]=0;
    cout<<"yapıldı";

}
    if(res1.at<Vec3b>(i-1,j-1)[0]>=200){
    yap(i-1,j-1,&res1);
    res1.at<Vec3b>(i-1,j-1)[0]=0;
    res1.at<Vec3b>(i-3,j-3)[1]=255;
    res1.at<Vec3b>(i-3,j-3)[2]=0;

    }
    if(res1.at<Vec3b>(i-1,j)[0]>=200){
    yap(i-1,j,&res1);
    res1.at<Vec3b>(i-1,j)[0]=0;
    res1.at<Vec3b>(i-1,j)[1]=255;
    res1.at<Vec3b>(i-1,j)[2]=0;

    }

    if(res1.at<Vec3b>(i-1,j+1)[0]>=200){
    res1.at<Vec3b>(i-1,j+1)[0]=0;
    res1.at<Vec3b>(i-1,j+1)[1]=255;
    res1.at<Vec3b>(i-1,j+1)[2]=0;

    }
    if(res1.at<Vec3b>(i,j-1)[0]>=200){
    yap(i,j-1,&res1);
    res1.at<Vec3b>(i,j-1)[0]=0;
    res1.at<Vec3b>(i,j-1)[1]=255;
    res1.at<Vec3b>(i,j-1)[2]=0;

    }
    if(res1.at<Vec3b>(i,j+1)[0]>=200){
    yap(i,j+1,&res1);
    res1.at<Vec3b>(i,j+1)[0]=0;
    res1.at<Vec3b>(i,j+1)[1]=255;
    res1.at<Vec3b>(i,j+1)[2]=0;

    }
    if(res1.at<Vec3b>(i+1,j-1)[0]>=200){
    yap(i+1,j-1,&res1);
    res1.at<Vec3b>(i+1,j-1)[0]=0;
    res1.at<Vec3b>(i+1,j-1)[1]=255;
    res1.at<Vec3b>(i+1,j-1)[2]=0;

    }
    if(res1.at<Vec3b>(i+1,j)[0]>=200){
    yap(i+1,j,&res1);
    res1.at<Vec3b>(i+1,j)[0]=0;
    res1.at<Vec3b>(i+1,j)[1]=255;
    res1.at<Vec3b>(i+1,j)[2]=0;

    }
    if(res1.at<Vec3b>(i+1,j+1)[0]>=200){
    yap(i+1,j+1,&res1);
    res1.at<Vec3b>(i+1,j+1)[0]=0;
    res1.at<Vec3b>(i+1,j+1)[1]=255;
    res1.at<Vec3b>(i+1,j+1)[2]=0;
    }
 }

void mouseTikla(int evt, int x, int y, int flags, void* param) 
{   Vec3b color;  
Mat* rgb = (Mat*) param;

Mat p;

p=*rgb;
if (flags == (CV_EVENT_LBUTTONDOWN+CV_EVENT_FLAG_CTRLKEY)) 
{ 
    yap(y,x,&p);

    cout<<x<<y;
 }

 }

int main(){
Mat res;
res=imread("C:/Users/giray/Desktop/27.jpg");
int i;
int j;

//res1.data[res.channels()*(res.cols*(i)+(j))];

namedWindow("Secim", 1);

setMouseCallback("Secim", mouseTikla, &res);
imshow("Secim", res);

waitKey(0);

return 0;
}

【问题讨论】:

  • 你说你“得到一个内存错误”,你是什么意思?什么错误?你从哪里得到错误?您是否尝试过调试代码以查找或定位错误,或者在操作中捕获错误?
  • 顺便说一句,在yap 函数中我看到你修改了res1 很多。但它是函数内部的局部变量。 (早期的)递归调用不会看到那些(后来的)更改,并且当函数返回并且res1 超出范围时,更改将丢失。您是否检查过您的索引算术没有超出范围(ij 加/减一)?

标签: c++ visual-studio opencv vector out-of-memory


【解决方案1】:

这段代码错了千百遍……

  1. 如果没有递归,就不要使用递归
  2. 为什么您实际上创建了这么多指向该单个图像的指针?
  3. 格式化真的很有帮助。
  4. 这里的内存重新分配简直太疯狂了。

这是您的代码的更好版本:

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <queue>

using namespace cv;
using namespace std;

void yap(int i,int j, Mat* res){
    queue<pair<int, int>> q;


    q.push(pair<int, int>(i, j));
    while (!q.empty())
    {
        pair<int, int> p = q.front();
        q.pop();

        if ((p.first < 0) ||
            (p.second < 0) ||
            (p.first >= res->rows) ||
            (p.second >= res->cols))
            continue;

        if (res->at<Vec3b>(p.first, p.second)[0] > 200)
        {
            res->at<Vec3b>(p.first, p.second) = {0, 255, 0};
            q.push(pair<int,int>(p.first - 1, p.second - 1));
            q.push(pair<int,int>(p.first + 1, p.second + 1));
            q.push(pair<int,int>(p.first - 1, p.second + 1));
            q.push(pair<int,int>(p.first + 1, p.second - 1));
            q.push(pair<int,int>(p.first + 1, p.second));
            q.push(pair<int,int>(p.first - 1, p.second));
            q.push(pair<int,int>(p.first, p.second + 1));
            q.push(pair<int,int>(p.first, p.second - 1));
        }
    }

}

void mouseTikla(int evt, int x, int y, int flags, void* param)
{
    Mat* rgb = (Mat*) param;

    if (evt == CV_EVENT_LBUTTONDOWN)
    {
        yap(y,x,rgb);
        imshow("Secim", *rgb);
    }
}

int main(){
    Mat res;
    res=imread("put_your_path_here");
    namedWindow("Secim", 1);

    setMouseCallback("Secim", mouseTikla, &res);
    imshow("Secim", res);
    waitKey(0);

    return 0;
}

【讨论】:

  • 嘿,对不起,错过了您使用 Ctrl 键。如果您使用我的示例,请修复它。
  • 我想协调我点击的像素,而我让男人穿绿色我写了代码获取坐标,但我无法实现你的代码。我的代码在下面。 @Leontyev Georgiy
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 2012-11-27
  • 1970-01-01
相关资源
最近更新 更多