我在Windows 8和VS2012上使用OpenCV2.4.5。
在向量上调用erase时,我遇到了一个奇怪的异常。这是我的代码,例外是在最后一行:
FINGERTIP_API int PalmTrackingProcess(
const Mat& I_ycbcr,
Mat& I_depth,
sFTHistory& history,
sFTResult& result)
{
static int gilcount=0;
gilcount++;
//function [success, results, vars] = PalmTrackingProcess(YCBCR, Depth, vars)
// if vars.frame_i==300 % 300 5fingers 480 1finger 400 spread
// vars.frame_i;
//end
//
//% RGB = ycbcr2rgb(double(YCBCR/255));
//% RGB = colorspace('RGB<-YCbCr',double(YCBCR));
//results.success = 1;
result.success = true;
//success = 1;
bool success = true;
//results.Palm1 = [];
result.Palm1 = 0;
//results.Palm2 = [];
result.Palm2 = 0;
//
//SEdepth = vars.SEdepth;
Mat SEdepth = history.SEdepth;
//Gaussian = vars.Gaussian;
Mat Gaussian = history.Gaussian;
//BWpalmFilt = vars.BWpalmFilt;
Mat BWpalmFilt = history.BWpalmFilt;
//% Gaussian3D = vars.Gaussian3D;
Mat Gaussian3D = history.Gaussian3D;
//peak2valleyRatio = vars.peak2valleyRatio;
double peak2valleyRatio = history.peak2valleyRatio;
//% SE1 = vars.SE1;
//% image_object.RGB = RGB;
//% image_object.YCBCR = YCBCR/255;
//image_object.Depth = Depth;
//
//
//%% Foreground Mask segmentation
//% foregroundMask = ForegroundDetectorMask( RGB,vars.foregroundDetector);
//% foregroundMask = imopen(foregroundMask,vars.SE1);
//% foregroundMask = imclose(foregroundMask,vars.SEskin);
//% foregroundMask = imopen(foregroundMask,vars.SEskin);
//% Mask = find(imfill(foregroundMask,'holes'));
//% third_dim_add = size(Depth,1) * size(Depth,2);
//% image_object.foreRGB = zeros(size(RGB),'single');
//% image_object.foreRGB([Mask; (Mask+third_dim_add); (Mask+2*third_dim_add)]) = RGB([Mask; (Mask+third_dim_add); (Mask+2*third_dim_add)]);
//% image_object.foreDepth = 2047*ones(size(Depth),'single');
//% image_object.foreDepth(Mask) = Depth(Mask);
//% Mask = find(ones(size(Depth)));
// Depth(350:end,:) = 2047; Gidi UDPATE: 27.12.2013
for(int i = 0; i < I_depth.rows; i++)
{
unsigned short* I_depth0 = I_depth.ptr<unsigned short>(i);
for(int j = 349; j < I_depth.cols; j++)
{
I_depth0[j] = 2047;
}
}
//Mask = find(Depth<vars.maxSkinDepth);
assert(I_depth.isContinuous());
int size = I_depth.rows * I_depth.cols;
int* tmp = new int[size];
int count = 0;
const unsigned short* I_depthPtr = I_depth.ptr<unsigned short>(0);
for(int i = 0; i < size; i++)
{
if(I_depthPtr[i] < history.maxSkinDepth)
{
tmp[count] = i;
count++;
}
}
Mat mask(count, 1, CV_32S, tmp);
//
//
//%% Skin Tone Segmentation (need to implement training and improved covariance)
//[SkinMask,h,s,v,vars]=SegmentSkin(YCBCR,Mask,vars);
Mat skinMask;
Mat h, s, v;
SegmentSkin(I_ycbcr, mask, history, skinMask, h, s, v);
mask.release();
delete [] tmp;
//% image_object.colorFiltDepth(SkinMask) = Depth(SkinMask);
//% image_object.colorFiltRGB = zeros(size(RGB),'single');
//% image_object.colorFiltRGB([SkinMask; (SkinMask+third_dim_add); (SkinMask+2*third_dim_add)]) = RGB([SkinMask; (SkinMask+third_dim_add); (SkinMask+2*third_dim_add)]);
//
//
//%% Depth Segmentation
//depthHist = histc(Depth(SkinMask),100:1000);
double minDepth = 0;
double maxDepth = 0;
int skinMaskSize = 0;
int* skinMask0 = 0;
const unsigned short* I_depth0 = I_depth.ptr<unsigned short>(0);
if(!skinMask.empty())
{
assert(skinMask.isContinuous() && I_depth.isContinuous());
skinMaskSize = skinMask.rows * skinMask.cols;
skinMask0 = skinMask.ptr<int>(0);
int* skinDepthAr = new int[skinMaskSize];
for(int i = 0; i < skinMaskSize; i++)
{
skinDepthAr[i] = I_depth0[skinMask0[i]];
}
Mat skinDepth(1, skinMaskSize, CV_32S, skinDepthAr);
Mat depthHist = MatlabFunctions::histc(skinDepth, 100, 1000);
skinDepth.release();
delete [] skinDepthAr;
//% test = conv(depthHist,1/10*[1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 ]','same');
//minDepth = find(depthHist>80,1,'first') + 90;
double depthHistLength = depthHist.cols * depthHist.rows;
const unsigned short* depthHist0 = depthHist.ptr<unsigned short>(0);
for(int i = 0; i < depthHistLength; i++)
{
if(depthHist0[i] > 80)
{
minDepth = i + 91.0;
break;
}
}
}
//if isempty(minDepth)
if(!minDepth)
{
//maxDepth = NaN; minDepth = NaN;
minDepth = numeric_limits<double>::quiet_NaN();
//vars.maxSkinDepth = 1000;
history.maxSkinDepth = 1000;
}
//else
else
{
//maxDepth = minDepth+75;
maxDepth = minDepth + 50;
//vars.maxSkinDepth = minDepth+100;
//history.maxSkinDepth = minDepth + 100;
//end
}
//% figure(1) % Histogram of skin pixels
//% area(100:1000,depthHist);
//% hold on
//% plot(minDepth,1, 'or','MarkerSize',10,'MarkerFaceColor','g')
//% plot(maxDepth,1, 'or','MarkerSize',10,'MarkerFaceColor','g')
//% hold off
//DepthMask = SkinMask((Depth(SkinMask)>minDepth & Depth(SkinMask)<maxDepth) );% | Depth(SkinMask)==0
// DepthMaskMorph = false(size(Depth));
//DepthMaskMorph(DepthMask) = true;
Mat DepthMaskMorph(I_depth.rows, I_depth.cols, CV_8U, Scalar::all(0));
int* depthMaskAr = 0;
if(skinMaskSize)
depthMaskAr = new int[skinMaskSize];
unsigned char* DepthMaskMorph0 = DepthMaskMorph.ptr<unsigned char>(0);
count = 0;
for(int i = 0; i < skinMaskSize; i++)
{
unsigned short val = I_depth0[skinMask0[i]];
if(val > minDepth && val < maxDepth)
{
depthMaskAr[count] = skinMask0[i];
DepthMaskMorph0[skinMask0[i]] = 1;
count++;
}
}
auto mat_deleter = [](Mat * m){delete [] m->data; m->release(); delete m;};
std::unique_ptr<Mat, decltype(mat_deleter)> depthMatToPalmAndFingers(new Mat(1, count, CV_32S, depthMaskAr), mat_deleter);
//imshow("Test", DepthMaskMorph.t() * 255);
//waitKey(0);
//Mat DepthMask(1, count, CV_32S, depthMaskAr);
// const int * currentRow = mask.ptr<int >(0);
//DepthMaskMorph = imclose(DepthMaskMorph,SEdepth);
Mat DepthMaskMorphClosed;
morphologyEx(DepthMaskMorph, DepthMaskMorphClosed, MORPH_CLOSE, SEdepth);
//imshow("Test", DepthMaskMorphClosed.t() * 255);
//waitKey(0);
//DepthMaskMorph = imfill(DepthMaskMorph,'holes');
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Mat tmpImage(DepthMaskMorphClosed.rows, DepthMaskMorphClosed.cols, CV_8U);
DepthMaskMorphClosed.copyTo(tmpImage);
findContours( tmpImage, contours, hierarchy, CV_RETR_TREE , CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
// skipping parent contours
int index = 0;
int offset = 0;
for (auto it = hierarchy.cbegin(); it != hierarchy.cend(); it++)
{
if (((*it)[2] != -1) && ((*it)[3] == -1))
{
contours.erase(contours.begin() + index - offset); //<== EXCEPTION
offset++;
}
index ++;
}
我在index = 19和offset = 0时遇到异常。我在尝试时也遇到异常:
编辑:这是我得到的例外:
Unhandled exception at 0x000007F8CAAABD59 (ntdll.dll) in FingerTipTest.exe: 0xC0000374: A heap has been corrupted (parameters: 0x000007F8CAB005F0).
我不知道这怎么可能发生。有人能指出我会导致什么原因吗?
谢谢,
吉尔。
答案 0 :(得分:1)
我会尝试向后迭代层次结构(从rbegin()开始并向下移动到rend()) 当擦除矢量条目时,这通常更安全和更简单。 我不确定它会解决您的问题,但它会简化代码并使其更容易调试。
答案 1 :(得分:0)
我不知道为什么,但当我将其改为使用OpenCV 2.4.7时,异常消失了
答案 2 :(得分:-1)
您正在向random_access迭代器添加1,它甚至可以是指针本身,具体取决于您使用的实现。为什么不尝试:
vector<vector<Point> >::iterator it = contours.begin();
std::advance(it, 1);
contours.erase(it);
这也应该有效:
contours.erase(++contours.begin());
您应该添加代码以在从不是容器的开头或结尾的位置擦除之前检查大小。