zoukankan      html  css  js  c++  java
  • 圆形环绕字 从直角坐标到极坐标的转换

     
     
    极坐标通常用于校正图像中的圆形物体或者包含在圆环中的物体。
    如上图所示 : 设原图变换的中心坐标(即圆心坐标)为 (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;
    }
     





  • 相关阅读:
    A1066 Root of AVL Tree (25 分)
    A1099 Build A Binary Search Tree (30 分)
    A1043 Is It a Binary Search Tree (25 分) ——PA, 24/25, 先记录思路
    A1079; A1090; A1004:一般树遍历
    A1053 Path of Equal Weight (30 分)
    A1086 Tree Traversals Again (25 分)
    A1020 Tree Traversals (25 分)
    A1091 Acute Stroke (30 分)
    A1103 Integer Factorization (30 分)
    A1032 Sharing (25 分)
  • 原文地址:https://www.cnblogs.com/xiaomaLV2/p/2554936.html
Copyright © 2011-2022 走看看