2016-12-12 2 views
-1

Фото здесь:ошибки памяти с помощью OpenCV

image

Я хочу увидеть этот белый человек в зеленый цвет, когда я нажал левой кнопкой мыши и клавишу [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; 
} 
+1

Вы говорите, что «получить ошибку памяти», что вы имеете в виду под этим? Какая ошибка? Где вы получаете сообщение об ошибке? Вы пробовали отлаживать свой код, чтобы найти или найти ошибку, или поймать ошибку в действии? –

+0

Кстати, в функции 'yap' я вижу, что вы много изменяете' res1'. Но это локальная переменная внутри функции. (Ранние) рекурсивные вызовы не будут видеть эти (более поздние) изменения, и изменения будут потеряны, когда функция вернется, и 'res1' выходит за рамки. И проверили ли вы, что вы не выходите за пределы своей арифметики индекса ('i' и' j' plus/minus one)? –

ответ

0

Этот код настолько неправильно в тысячу ладов ...

  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; 
} 
+0

Хех, извините, пропустил, что вы использовали клавишу Ctrl. Исправьте его, если вы будете использовать мой пример. –

+0

THX много я голосую u –

+0

Я хочу, чтобы координировать, что я нажал на пиксель, пока я делаю человека в зеленом я написал код получить координаты, но я не могу реализовать ваш код. Мой код ниже. @ Леонтьев Георгий –

Смежные вопросы