amsw11 2015-11-15 11:54 采纳率: 0%
浏览 2325

求图像连通区域数的一个代码一直提示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:\03.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;
}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 YoloV5 第三方库的版本对照问题
    • ¥15 请完成下列相关问题!
    • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
    • ¥15 求daily translation(DT)偏差订正方法的代码
    • ¥15 js调用html页面需要隐藏某个按钮
    • ¥15 ads仿真结果在圆图上是怎么读数的
    • ¥20 Cotex M3的调试和程序执行方式是什么样的?
    • ¥20 java项目连接sqlserver时报ssl相关错误
    • ¥15 一道python难题3
    • ¥15 牛顿斯科特系数表表示