问题描述
- 求图像连通区域数的一个代码一直提示vector subscript out of range,求问
-
skin是用来提取肤色区域的,不加这段可以正常运行,加了就不行了
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;void Two_Pass(const cv::Mat& binImg, cv::Mat& lableImg) //两遍扫描法
{
if (binImg.empty() ||
binImg.type() != CV_8UC1)
{
cout<<"no picture"<<endl;
return;
}// 第一个通路
lableImg.release();
binImg.convertTo(lableImg, CV_32SC1);int label = 1;
std::vector labelSet;
labelSet.push_back(0);labelSet.push_back(1);
int rows = binImg.rows - 1;
int cols = binImg.cols - 1;
for (int i = 1; i < rows; i++)
{
int* data_preRow = lableImg.ptr(i-1);
int* data_curRow = lableImg.ptr(i);
for (int j = 1; j < cols; j++)
{
if (data_curRow[j] == 1)
{
std::vector neighborLabels;
neighborLabels.reserve(2);
int leftPixel = data_curRow[j-1];
int upPixel = data_preRow[j];
if ( leftPixel > 1)
{
neighborLabels.push_back(leftPixel);
}
if (upPixel > 1)
{
neighborLabels.push_back(upPixel);
}if (neighborLabels.empty()) { labelSet.push_back(++label); // 不连通,标签+1 data_curRow[j] = label; labelSet[label] = label; } else { std::sort(neighborLabels.begin(), neighborLabels.end()); int smallestLabel = neighborLabels[0]; data_curRow[j] = smallestLabel; // 保存最小等价表 for (size_t k = 1; k < neighborLabels.size(); k++) { int tempLabel = neighborLabels[k]; int& oldSmallestLabel = labelSet[tempLabel]; if (oldSmallestLabel > smallestLabel) { labelSet[oldSmallestLabel] = smallestLabel; oldSmallestLabel = smallestLabel; } else if (oldSmallestLabel < smallestLabel) { labelSet[smallestLabel] = oldSmallestLabel; } } } } }
}
// 更新等价对列表
// 将最小标号给重复区域
cout<<labelSet.size();
for (size_t i = 2; i < labelSet.size(); i++)
{
int curLabel = labelSet[i];
int preLabel = labelSet[curLabel];
while (preLabel != curLabel)
{
curLabel = preLabel;
preLabel = labelSet[preLabel];
}
labelSet[i] = curLabel;
} ;for (int i = 0; i < rows; i++)
{
int* data = lableImg.ptr(i);
for (int j = 0; j < cols; j++)
{
int& pixelLabel = data[j];
pixelLabel = labelSet[pixelLabel];}
}
}
//彩色显示
cv::Scalar GetRandomColor()
{
uchar r = 255 * (rand()/(1.0 + RAND_MAX));
uchar g = 255 * (rand()/(1.0 + RAND_MAX));
uchar b = 255 * (rand()/(1.0 + RAND_MAX));
return cv::Scalar(b,g,r);
}void LabelColor(const cv::Mat& labelImg, cv::Mat& colorLabelImg)
{
if (labelImg.empty() ||
labelImg.type() != CV_32SC1)
{
return;
}std::map colors;
int rows = labelImg.rows;
int cols = labelImg.cols;colorLabelImg.release();
colorLabelImg.create(rows, cols, CV_8UC3);
colorLabelImg = cv::Scalar::all(0);for (int i = 0; i < rows; i++)
{
const int* data_src = (int*)labelImg.ptr(i);
uchar* data_dst = colorLabelImg.ptr(i);
for (int j = 0; j < cols; j++)
{
int pixelValue = data_src[j];
if (pixelValue > 1)
{
if (colors.count(pixelValue) <= 0)
{
colors[pixelValue] = GetRandomColor();
}cv::Scalar color = colors[pixelValue]; *data_dst++ = color[0]; *data_dst++ = color[1]; *data_dst++ = color[2]; } else { data_dst++; data_dst++; data_dst++; } }
}
}Mat skin(Mat &img){
Mat out;medianBlur( img, out, 15);
// GaussianBlur(image,out,Size(17,17),0,0); //遍历图像得到符合肤色特征的像素点 记录于count int count=0; for(int i=0;i<out.rows;i++) { for(int j=0;j<out.cols;j++) { int r,g,b; //图像的R,G,B信息 b=out.at<Vec3b>(i,j)[0]; g=out.at<Vec3b>(i,j)[1]; r=out.at<Vec3b>(i,j)[2]; // if(i==100&&j==i)cout<<r<<","<<g<<","<<b<<endl; double iYIQ,Cr,Cb; //YIQ,YCbCr颜色空间的I,Cr,Cb值,由转换公式获得 iYIQ = 0.596*(double)r - 0.275*(double)g - 0.321*(double)b; Cb = -0.148*(double)r - 0.291*(double)g + 0.439*(double)b + 128; Cr = 0.439*(double)r - 0.368*(double)g - 0.071*(double)b + 128; // if(i==100&&j==i)cout<<iYIQ<<","<<Cb<<","<<Cr<<endl; if((iYIQ<=85&&iYIQ>=15)&&(Cb>88&&Cb<133)&&(Cr>122&&Cr<169))count++; //if(r>95 && g>40 && b>20 && r>g && r>b && max(r,g,b)-min(r,g,b)>15 && abs(r-g)>15)count++; else {out.at<Vec3b>(i,j)[0]=0;out.at<Vec3b>(i,j)[1]=0;out.at<Vec3b>(i,j)[2]=0;} } } return out;
}
int main()
{cv::Mat binImage = cv::imread("F:3.jpg");
Mat out=skin(binImage);
imshow("xixi",out);
waitKey(0);
Mat out1;
cv::cvtColor(out,out1,CV_BGR2GRAY);
imshow("xixi1",out1);
waitKey(0);
Mat out2;
cv::threshold(out1, out1, 1, 255, CV_THRESH_BINARY_INV);
if(out1.empty()==1)cout<<"no picture!!"<<endl;
imshow("xixi2",out1);
waitKey(0);cv::Mat labelImg;
Two_Pass(out1, labelImg);
//Seed_Filling(binImage, labelImg);
//彩色显示
cv::Mat colorLabelImg;
LabelColor(labelImg, colorLabelImg);
cv::imshow("colorImg", colorLabelImg);
/* //灰度显示
cv::Mat grayImg;
labelImg *= 10;
labelImg.convertTo(grayImg, CV_8UC1);
cv::imshow("labelImg", grayImg);
*/cv::waitKey(0);
return 0;
}
解决方案
vector subscript out of range
vector subscript out of range .
vector subscript out of range问题解决方案之一