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