分享

使用OpenCv的cvMinAreaRect2函数获取轮廓的可倾斜最小矩形区域

 delphi_笔记 2019-09-23

procedure TFrmMain.BtnFreeManClick(Sender: TObject);
var
  oImg, oImg2, oImg3: PIplImage;
  contours: PCvSeq;
  p: Pchar;
  pSeq: PCvSeq;
  oMem: TCvMemStorage;
  I, nCnt, nMaxArea, total: Integer;
  stor: pCvMemStorage;
  cont: pCvSeq;
  pnt:CvPoint;
  sFileName: string;
  pChain: PCvChain;
  nDistance: Integer;
  nDelay: Integer;
  IsDeflection: Boolean;
  seqReader: CvSeqReader;
  pChainReader: PCvChainPtReader;
  chainReader: CvChainPtReader;
  c: PCvChain;
  arr: TIntegerArr;
  aPoints: array of CvPoint2D32f;
  pS: PSingle;
  box: CvBox2D;
  pointMat: PCvMat;
  aboxPoint: array[0..3] of CvPoint2D32f;
  lines_header: CvSeq;
  lines_block: CvSeqBlock;
  lines: PCvSeq;
begin
  Randomize;
  nMaxArea := 0;
  OpenDialog1.InitialDir := ExtractFilePath(ParamStr(0)) + 'pic';
  if OpenDialog1.Execute then
    sFileName := OpenDialog1.FileName
  else
    Exit;
  nDelay := THelp.GetSysTickCount64;
  stor := cvCreateMemStorage(0);
  cont := cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), stor);
  oImg := cvLoadImage(PChar(sFileName), CV_LOAD_IMAGE_GRAYSCALE);
  oImg3 := cvCreateImage(cvSize_(oImg.Width, oImg.Height), oImg.Depth, oImg.NChannels);
  oImg2 := cvCloneImage(oImg);
  cvAdaptiveThreshold(oImg, oImg3, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 11, 5);
  cvCanny(oImg, oImg, StrToInt(EdtCanny_P1.Text), StrToInt(EdtCanny_P2.Text));
  cvSaveImage('C:\1.bmp', oImg3);
  cvSaveImage('C:\2.bmp', oImg);
  cvNamedWindow('Example1', CV_WINDOW_AUTOSIZE);
  cvNamedWindow('Example2', CV_WINDOW_AUTOSIZE);
  pChain := nil;
  nCnt := cvFindContours(oImg, stor, @pChain, SizeOf(CvChain), CV_RETR_LIST, CV_CHAIN_CODE, cvPoint_(0,0));
  cont := cvApproxChains(PCvSeq(pChain), stor, CV_CHAIN_APPROX_SIMPLE, 0, 0, 1);  //多边形逼近
  cvZero(oImg);
  nCnt := 0;
  while cont <> nil do
  begin
    if cont.total > 2 then
    begin
      SetLength(arr, cont.total * 2);
      SetLength(aPoints, High(aPoints) + cont.total + 1);
      cvCvtSeqToArray(cont, @arr[0], CvSlice_(0, CV_WHOLE_SEQ_END_INDEX));
      for i := Low(arr) to High(arr) div 2 do
      begin
        aPoints[nCnt] := cvPoint2D32f_(arr[i * 2], arr[i * 2 + 1]);
        Inc(nCnt);
      end;
    end;
    cont := cont.h_next;
  end;
  pointMat := cvCreateMat(1, nCnt * 2, CV_32FC2);
  pS := PSingle(pointMat.ptr);
  for i := Low(aPoints) to High(aPoints) do
  begin
    pS^ := aPoints[i].x;
    Inc(pS);
    pS^ := aPoints[i].y;
    Inc(pS);
  end;

  lines := cvMakeSeqHeaderForArray(CV_32FC2, SizeOf(CvSeq), SizeOf(Single) * 2, @aPoints[0], High(aPoints) + 1, @lines_header, @lines_block);
  box := cvMinAreaRect2(lines);
  cvBoxPoints(box, @aboxPoint[0]);
  for i := Low(aboxPoint) to High(aboxPoint) do
    cvLine(oImg3, CvPoint2D32fToCvPoint(aboxPoint[i]), CvPoint2D32fToCvPoint(aboxPoint[(i + 1) mod 4]), CV_RGB(100, 100, 100), 2, 8, 0);
  cvSaveImage('C:\2.bmp', oImg3);
  cvShowImage('Example1', oImg);
  cvShowImage('Example2', oImg3);
  cvWaitKey(0);
  cvReleaseImage(oImg);
  cvReleaseImage(oImg2);
  cvDestroyWindow('Example1');
  cvDestroyWindow('Example2');
end;

原图:

获取的倾斜矩形:

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多