2016-12-23 4 views
0

Когда я запускаю этот код я получаю A heap has been corruptedПочему куча повреждена?

Вот мой код:

#include "opencv2\opencv.hpp" 
using namespace cv; 

//This program with take a Video, separate it into it's blue, green and red channels and display them. 
//It will then convert the video into HSV and do the same with it's hue, saturation, and value channels 
int main() { 
    Mat src, hsv, hls; 
    Mat blue, green, red, hue1, saturation1, value, hue2, light, saturation2; 
    bool quit = false; 
    VideoCapture videoCapture(0); 
    //create window 
    cv::namedWindow("SplitImage"); 
    while (!quit) { 
     //read in image 
     videoCapture >> src; 
     //convert image to hsv and hsl 
     cvtColor(src, hsv, CV_BGR2HSV); 
     cvtColor(src, hls, CV_BGR2HLS); 

     //copy src to blue, green, and red matrices 
     src.copyTo(blue); 
     src.copyTo(green); 
     src.copyTo(red); 

     //copy hsv to hue1, saturation1, and value matrices 
     hsv.copyTo(hue1); 
     hsv.copyTo(saturation1); 
     hsv.copyTo(value); 

     //copy hls to hue2, light and saturation2 
     hls.copyTo(hue2); 
     hls.copyTo(light); 
     hls.copyTo(saturation2); 

     //resize windows 
     Size size = Size(200, 200); 
     resize(src, src, size); 
     resize(hsv, hsv, size); 
     resize(hls, hls, size); 
     resize(blue, blue, size); 
     resize(green, green, size); 
     resize(red, red, size); 
     resize(hue1, hue1, size); 
     resize(saturation1, saturation1, size); 
     resize(value, value, size); 
     resize(hue2, hue2, size); 
     resize(light, light, size); 
     resize(saturation2, saturation2, size); 

     //get number of rows, columns, and channnels 
     int nRows = size.height; 
     int channels = src.channels(); 
     int nCols = size.width * channels; 

     //put matrices in array 
     Mat matrices[9] = { blue, green, red, hue1, saturation1, value, hue2, light, saturation2 }; 
     //declare the pointers that will access the matrices' data 
     uchar * p[9]; 
     //for readability I will access the pointer with 
     //these constants instead of numbers 
     const int blueIdx = 0, greenIdx = 1, redIdx = 2, 
      hue1Idx = 3, sat1Idx = 4, valueIdx = 5, 
      hue2Idx = 6, lightIdx = 7, sat2Idx = 8; 
     //make blue matrix blue, green matrix green and red matrix red 
     //and make hue matrix only have hue, saturation matrix only have saturation, and value matrix only have value 
     for (int row = 0; row < nRows; row++) { 
      //each element in p points to the first element in the row of each matrix 
      //for (int i = 0; i < 9; i++) { 
      // p[i] = matrices[i].ptr<uchar>(row); 
      //} 
      for (int col = 0; col < nCols; col += channels) { 
       //std::cout <<"separating at pixel coordinate"<< "(" << col << ", " << row<<")" << std::endl; 
       // remember that pointer + 0 is the blue pixel, pointer + 1 is the green 
       // pixel and pointer + 2 is the red pixel 
       //turn pixel in blue matrix blue 
       /*p[blueIdx][col + 1] = 0; 
       p[blueIdx][col + 2] = 0;*/ 
       blue.data[row*nCols + col*channels + 1] = 0; 
       blue.data[row*nCols + col*channels + 2] = 0; 
       //turn pixel in green matric green 
       //p[greenIdx][col + 0] = 0; 
       //p[greenIdx][col + 2] = 0; 
       green.data[row*nCols + col*channels + 0] = 0; 
       green.data[row*nCols + col*channels + 2] = 0; 
       //turn pixel in red matrix red 
       //p[redIdx][col + 0] = 0; 
       //p[redIdx][col + 1] = 0; 
       red.data[row*nCols + col*channels + 0] = 0; 
       red.data[row*nCols + col*channels + 1] = 0; 

       // remember that pointer + 0 is the hue pixel, pointer + 1 is the saturation 
       // pixel and pointer + 2 is the value pixel 
       //turn pixel in hue matrix hue 
       /*p[hue1Idx][col + 1] = 0; 
       p[hue1Idx][col + 2] = 0;*/ 
       hue1.data[row*nCols + col*channels + 1] = 0; 
       hue1.data[row*nCols + col*channels + 2] = 0; 
       //turn pixel in saturation matric saturation 
       /*p[sat1Idx][col + 0] = 0; 
       p[sat1Idx][col + 2] = 0;*/ 
       saturation1.data[row*nCols + col*channels + 0] = 0; 
       saturation1.data[row*nCols + col*channels + 2] = 0; 
       //turn pixel in value matrix value 
       /*p[valueIdx][col + 0] = 0; 
       p[valueIdx][col + 1] = 0;*/ 
       value.data[row*nCols + col*channels + 0] = 0; 
       value.data[row*nCols + col*channels + 1] = 0; 

       //turn pixel in hue matrix hue 
       /*p[hue2Idx][col + 1] = 0; 
       p[hue2Idx][col + 2] = 0;*/ 
       hue2.data[row*nCols + col*channels + 1] = 0; 
       hue2.data[row*nCols + col*channels + 2] = 0; 
       //turn pixel in saturation matric saturation 
       /*p[lightIdx][col + 0] = 0; 
       p[lightIdx][col + 2] = 0;*/ 
       light.data[row*nCols + col*channels + 0] = 0; 
       light.data[row*nCols + col*channels + 2] = 0; 
       //turn pixel in light matrix value 
       /*p[sat2Idx][col + 0] = 0; 
       p[sat2Idx][col + 1] = 0;*/ 
       saturation2.data[row*nCols + col*channels + 0] = 0; 
       saturation2.data[row*nCols + col*channels + 1] = 0; 


      } 
     } 

     //put indentifying text on each matrix 
     Point textPosition = Point(5, 10); 
     putText(src, "src", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2);//THIS IS LINE 131 WHERE THE ERROR OCCURS 
     putText(hsv, "hsv", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(hls, "hls", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(blue, "blue", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(green, "green", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(red, "red", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(hue1, "hue1", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(saturation1, "saturation", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(value, "value", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(hue2, "hue", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(light, "light", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 
     putText(saturation2, "saturation", textPosition, FONT_HERSHEY_PLAIN, 1, Scalar(255, 255, 255), 2); 

     //concatenate images 
     Mat topRow, middleRow, bottomRow, finalImage; 
     std::vector<Mat> top = { src, blue, green, red }; 
     std::vector<Mat> middle = { hsv, hue1, saturation1, value }; 
     std::vector<Mat> bottom = { hls, hue2, light, saturation2 }; 
     hconcat(top, topRow); 
     hconcat(middle, middleRow); 
     hconcat(bottom, bottomRow); 
     std::vector<Mat> allRows = { topRow, middleRow, bottomRow }; 
     vconcat(allRows, finalImage); 

     //show matrices in window 
     cv::imshow("SplitVideo", finalImage); 

     if(cv::waitKey(30) == 'q') quit = true; 
    } 
} 

код принимает видео с веб-а показывает красный зеленый и синий каналы, он затем преобразует его в HSV и показывает каналы насыщения насыщенности и значения, затем преобразует видео в HLS и показывает каналы оттенка и насыщения. Тезисы отображаются бок о бок в одном окне

Как вы можете видеть в коде, я заметил еще один способ сделать то же самое с помощью <Mat object>.ptr<uchar>(row), чтобы получить указатель на каждой строке, вместо того, чтобы использовать <Mat object>.data, чтобы получить указатель ко всем данным. Когда я использую метод комментариев, код работает без ошибок. Я мог бы просто использовать это, но я хочу знать, почему метод <Mat object>.data не работает.

Я уверен, что строки <Mat object>.data являются причиной ошибки, хотя ошибка не возникает в этих строках, потому что я получил ту же ошибку в другом приложении, которое также использует тот же код <Mat object>.data, и я получаю такая же ошибка. (то, что я написал, является более простым из двух приложений)

+2

Количество операций массива, как 'blue.data [строке * Ncols + цвет * Каналы + 1] = 0 'представляет прекрасную возможность писать мимо конца массива. У вашего кода есть куча. В этом примере ASSUMES 'row * nCols + col * channels + 1' меньше количества элементов в массиве (поскольку индексирование массива основано на нулевом значении) и в противном случае будет иметь доступ к концу массива. – Peter

+0

В соответствии с AddressSanitizer у вас есть переполнение переполнения кучи по крайней мере в этой строке: 'blue.data [row * nCols + col * channels + 1] = 0;', и эта ошибка будет повторяться в следующих похожих строках , –

+0

Это довольно плохая (и подверженная ошибкам) ​​реализация, особенно для цикла, обнуляющего элемент 18 элементов по элементам. Пара ['split'] (http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#split) и [' merge'] (http://docs.opencv.org/ 2.4/modules/core/doc/operations_on_arrays.html # merge) s вместе с одним матом нулей должны делать работу в пути, куда намного легче следовать. Возможно, даже ['mixChannels'] (http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#mixchannels)? –

ответ

2

Вы не должны умножать каналы col *. Вы уже продвигаете его по нескольким каналам в цикле. Поэтому вы должны написать, например.

blue.data[row*nCols + col + 1] = 0; 

т.д.

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