2013-11-20 4 views
0

Я новичок в opencv. Я пытаюсь сделать свертку изображения с использованием ядра, имеющего такой же размер, как и изображение в opencv C++. Я получаю сообщение об ошибке «Ошибка сегментации (core dumped)». Я проверил для инициализации переменных и для цикла. Но я не могу точно определить, в чем проблема. Кто-нибудь может помочь мне в выяснении проблемы. Мой код приведен ниже:Ошибка сегментации (сброс ядра) при поиске свертки изображений в opencv C++

#include<opencv2/highgui/highgui.hpp> 
#include "opencv2/imgproc/imgproc.hpp" 
#include<stdio.h> 
#include<iostream> 
#include<math.h> 
#include<cv.hpp> 

using namespace cv; 
using namespace std; 

Mat img; 
Mat kernel, gd, dest; 
int c = 120; 
double mysum = 0.0, mysum1 = 0.0, k = 0; 
int cent=0,radius=0; 
enum ConvolutionType { 
    /* Return the full convolution, including border */ 
    CONVOLUTION_FULL, 

    /* Return only the part that corresponds to the original image */ 
    CONVOLUTION_SAME, 

    /* Return only the submatrix containing elements that were not influenced by the  
    border  
    */ 
    CONVOLUTION_VALID 
}; 

void conv2(const Mat &img, const Mat& kernel, ConvolutionType type,Mat& dest) 
{ 

    Mat source = img; 
    if(CONVOLUTION_FULL == type) 
    { 
     source = Mat(); 
     const int additionalRows = kernel.rows - 1, additionalCols = kernel.cols - 1; 
     copyMakeBorder(img, source, (additionalRows + 1)/2, additionalRows/2, 
      (additionalCols + 1)/2, additionalCols/2, BORDER_CONSTANT, Scalar(0)); 
    } 

    flip(kernel, kernel, -1); 
    Point anchor(kernel.cols - kernel.cols/2 - 1, kernel.rows - kernel.rows/2 - 1); 
    int borderMode = BORDER_CONSTANT; 
    filter2D(source, dest, img.depth(), kernel, anchor, 0, borderMode); 

    if(CONVOLUTION_VALID == type) 
    { 
     dest = dest.colRange((kernel.cols - 1)/2, dest.cols - kernel.cols/2).rowRange((kernel.rows - 1)/2, dest.rows - kernel.rows/2); 
    } 
} 

int main() 
{ 
    img = imread("building1.jpg", CV_LOAD_IMAGE_COLOR); 
    dest.create(img.size(), img.type()); 
    gd.create(img.size(), img.type()); 

    for(int j = 0; j < img.rows; j++) 
    { 
     for(int i = 0; i < img.cols; i++) 
     { 
      radius = ((cent - i)^2 + (cent - j)^2); 
      gd.at<float>(j, i) = exp((-(radius)/c^2)); 

      mysum = mysum + gd.at<float>(j, i); 
     } 
     mysum1 = mysum1 + mysum; 
    } 

    k=1/mysum1; 
    cout<<endl<<k<<"\n"<<endl; 

    for(int j = 0; j < img.rows; j++) 
    { 
     for(int i = 0; i < img.cols; i++) 
     { 
      gd.at<float>(j, i) = k * gd.at<float>(j, i); 
     } 
    } 

    conv2(img, gd, CONVOLUTION_FULL, dest); 
    imshow("conv", dest); 
    waitKey(0); 
    return 0; 
} 
+1

ужасно отформатированный код; ( – berak

+1

кстати, а^Ь является исключающее Ь, не пау (а, б) – berak

+0

Вы проверили, в какой момент приходит эта ошибка Простой способ узнать это будет закомментировать майор? части вашего кода и посмотреть, не исчезла ли ошибка. –

ответ

1

При создании img

img = imread("building1.jpg", CV_LOAD_IMAGE_COLOR); 

он будет типа CV_UC3, то есть 3 байта на пиксель (по одному для каждого синего, зеленого и красного цвета).

Однако при доступе к изображению

gd.at<float>(j, i) = k * gd.at<float>(j, i); 

вы используете указатель с плавающей точкой. Поскольку поплавок равен 4 байтам, а не 3, вы получите доступ к памяти за пределами изображения или даже вашей программы. Последнее происходит, как указывает нарушение сегментации.

Возможно, лучше всего было бы скомпилировать ваш код в режиме отладки. Возможно, вы получите исключение из OpenCV, а не за нарушение сегментации.

Похоже, что вы, возможно, хотели это

img = imread("building1.jpg", CV_LOAD_IMAGE_GRAYSCALE); 
img.convertTo(img, CV_32FC1); 
... 

Кроме того, некоторые из вас код может быть значительно упрощена, например,

for(int j = 0; j < img.rows; j++) 
{ 
    for(int i = 0; i < img.cols; i++) 
    { 
     gd.at<float>(j, i) = k * gd.at<float>(j, i); 
    } 
} 

должен быть

gd = gd * k; 

Если доступ пикселей ПОСЛЕДОВАТЕЛЬНО с использованием at<>() очень неэффективно. См the efficient way

+0

Спасибо за ваш ответ sir. Я попытался с этим, снова появляется та же ошибка. – user2943871

+0

Сэр, я пробовал с этим, я не получаю эту ошибку. Большое вам спасибо, сэр .... – user2943871

+0

@ user2943871 Не говорите спасибо - примите и открепите ответ! (если вы хотите помочь в следующий раз :) – Bull

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