圆形环绕字 从直角坐标到极坐标的转换

 
 
极坐标通常用于校正图像中的圆形物体或者包含在圆环中的物体。
如上图所示 : 设原图变换的中心坐标(即圆心坐标)为 (Mr,Mc),图像上一点(r,c)极坐标变换后为(d,theta)
 
则 d = sqrt( (r - Mr) * (r - Mr) + (c - Mc ) * (c -Mc) )
     theta = atan2( - (r - Mr) / (c - Mc))
 
其反变换形式为 r = Mr - d sin(theta)
                              c= Mc + d cos(theta)
 
 
本程序基于opencv2.3
 
// polar.cpp : 定义控制台应用程序的入口点。
//
# include "stdafx.h"
# include "highgui.h"
# include "cv.h"
# include "cxcore.h"
# ifdef DEBUG
# pragma comment(lib, " opencv_core231d.lib")
# pragma comment(lib, "opencv_features2d231d.lib")
# pragma comment(lib, "opencv_flann231d.lib")
# pragma comment(lib, "opencv_gpu231d.lib")
# pragma comment(lib, "opencv_highgui231d.lib")
# pragma comment(lib, "opencv_imgproc231d.lib")
# else
# pragma comment(lib, "opencv_core231.lib")
# pragma comment(lib, "opencv_features2d231.lib")
# pragma comment(lib, "opencv_flann231.lib")
# pragma comment(lib, "opencv_gpu231.lib")
# pragma comment(lib, "opencv_highgui231.lib")
# pragma comment(lib, "opencv_imgproc231.lib")
# endif
/*
    函数:polar
    功能:获取极坐标变换图像尺寸
    参数:
        anglestart angleend 起止角度 [in]
        radiusstart radiusend 起止半径[in]
        accuracy 角度精度 [in]
        nwidth 宽 [out]
        nheight 高 [out]
        注:nwidth 表示角度
        nheight 表示半径
*/

int getpolarsize( int anglestart, int angleend, int radiusstart, int radiusend , float accuracy, int &nwidth , int &nheight)
{
    
     //if(radiusend <0 || radiusstart < 0 || radiusstart > radiusend ||
     //    anglestart <0 || angleend < 0 || anglestart> angleend )
     //    return 0;
    nheight = radiusend - radiusstart; 
    nwidth = ( int)( 1. 0 * (angleend - anglestart) / accuracy);
     //nwidth = (int)(2 * CV_PI * radiusend);
     return 1;
}
/*
    函数:polar
    功能:直角坐标转到极坐标
    参数:im_src 源图像                [in]
         im_dst 目的图像 [out]
         centerx centery 圆心坐标 [in]
         anglestart angleend 起止角度 [in]
         radiusstart radiusend 起止半径[in]
         accuracy 角度精度 [in]
         
    注:nwidth 表示角度
     nheight 表示半径
*/

void polar(IplImage * im_src ,IplImage *im_dst , int centerx , int centery , int anglestart, int angleend, int radiusstart, int radiusend , float accuracy)
{
     float d = 0. 0; // 点到圆中心的距离
     float theta = 0. 0; // 角度
    
     int nsrcwidth =im_src - >width;
     int nsrcheight = im_src - >height;
     int nsrcwidthstep = im_src - >widthStep;
     int ndstwisdthstep = im_dst - >widthStep;
     unsigned char *psrcpiexl = NULL;
     unsigned char *pdstpiexl = NULL;
    
    im_dst - >origin = 1;
     //src(x) = centerx - d * sin(theta)
     //src(y) = centery + d * cos(theta)
     int nsrcx = 0
     int nsrcy = 0 ;
     for ( float i = radiusstart ;i < radiusend ; ++i)
    {
         for ( float j = ( float)anglestart ; j <( float)angleend ; j +=accuracy)
        {
            nsrcx = 0
            nsrcy = 0 ;
            nsrcx = centerx - cvRound(i * sin(j * CV_PI / 180));
            nsrcy = centery + cvRound(i * cos(j * CV_PI / 180));
         //    printf("i:%d j:%f x:%d y:%d\n" ,cvRound(i),j,cvRound(i * sin(j)),cvRound(i * cos(j)));
            psrcpiexl = ( unsigned char *)(im_src - >imageData + nsrcy * nsrcwidthstep + nsrcx);
            pdstpiexl = ( unsigned char *)(im_dst - >imageData + cvRound((i -radiusstart) * ndstwisdthstep) + cvRound((j -anglestart) /accuracy));
             *pdstpiexl = *psrcpiexl;
        }
    }
     //
     //for (int i = 0 ; i < nsrcheight ; ++i)
     //{
     //    for (int j = 0 ; j < nsrcwidth ; ++j)
     //    {
     //    
     //    //    d = 0.0 ;
     //    //    theta = 0.0; 
     //    //    //1. 计算点到圆心距离d ,角度theta
     //    //    d = sqrt( 1.0*(i-centery)*(i-centery) + (1.0*j-centerx)*(j-centerx));
     //    //    theta = atan2(-1.0 * (i - centery) ,1.0*(j - centerx)) + 180;
     //    //    if (d< radiusstart || d > radiusend || theta < anglestart || theta > angleend)
     //    //        continue;
     //    //    theta = theta / accuracy;
     //    //    
     //        printf("d :%d theta :%d\n",(int)d,(int)theta);
     //    //    // 2 . 映射
     //    //    psrcpiexl = (unsigned char *)(im_src->imageData + i * nsrcwidthstep + j);
     //    //    pdstpiexl = (unsigned char *)(im_dst->imageData + (int)((d-radiusstart) * ndstwisdthstep) +(int)(theta-1.0*anglestart/accuracy));
     //        pdstpiexl = (unsigned char *)(im_dst->imageData + (((int)d-radiusstart) * ndstwisdthstep) +(int)(theta-anglestart/accuracy));
     //    //    if (*psrcpiexl !=255)
     //    //        continue;
     //    //    *pdstpiexl = *psrcpiexl;
     //    }
     //}
}
int _tmain( int argc, _TCHAR * argv[])
{
    IplImage * im_src = cvLoadImage( "POLRA.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    IplImage * im_show = cvCreateImage(cvGetSize(im_src), 8, 3);
    cvConvertImage(im_src,im_show);
     //1.二值化
    cvNot(im_src,im_src);
    IplImage * im_threshod = cvCreateImage(cvGetSize(im_src), 8, 1);
    cvThreshold(im_src,im_threshod, 0, 255,CV_THRESH_OTSU);
     //2.闭运算核*50 将字体连成一片
    IplImage * im_close = cvCreateImage(cvGetSize(im_src), 8, 1);
     int elementx = 50;
     int elementy = 50;
    IplConvKernel * element = cvCreateStructuringElementEx(elementx ,elementy,elementx / 2,elementy / 2,CV_SHAPE_RECT);
    cvMorphologyEx(im_threshod,im_close,NULL,element,CV_MOP_CLOSE);
    cvReleaseStructuringElement( &element);
    
    cvShowImage( "close",im_close);
     //3.查找轮廓
    CvMemStorage *storage = cvCreateMemStorage( 0);
    CvSeq * contour = NULL;
    cvFindContours(im_close,storage, &contour);
    CvPoint2D32f center;
     float radius;
     for (;contour != 0 ; contour =contour - >h_next)
    {
         // 4 . 最小外界圆
        cvMinEnclosingCircle(contour, &center, &radius);
        cvCircle(im_show,cvPointFrom32f(center),( int)radius,CV_RGB( 255, 0, 0));
        printf( "x:%d y:%d r:%d\n",( int)center.x,( int)center.y,( int)radius);
    }
     int nwidth = 0;
     int nheight = 0 ;
    getpolarsize( 0, 360,radius - 50,radius + 50,( float) 0. 4,nwidth,nheight);
    IplImage * im_dst = cvCreateImage(cvSize(nwidth,nheight), 8, 1);
    cvZero(im_dst);
    polar(im_threshod,im_dst,center.x,center.y, 0, 360,radius - 50,radius + 50,( float) 0. 4);
    cvShowImage( "polar",im_dst);
    cvShowImage( "threahold",im_threshod);
    cvShowImage( "show",im_show);
    cvWaitKey( - 1);
    cvReleaseImage( &im_dst);
    cvReleaseMemStorage( &storage);
    cvReleaseImage( &im_threshod);
    cvReleaseImage( &im_src);
    cvReleaseImage( &im_show);
     return 0;
}
 





转载于:https://www.cnblogs.com/xiaomaLV2/archive/2012/06/19/2554936.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值