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


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





  • 相关阅读:
    C++Primer 中间Sales_items.h头文件
    2014最不受欢迎10编程语言种
    解决ubuntu 14.04删ibus导致系统设置项目的损失后,,退出关机问题是不正常的
    会计翻译成英文
    Delphi 使用 Format格式话字符串的用法
    浅谈暂估应付账款的会计处理
    Delphi TcxTreelist 设置scrollbars 不起作用的原因
    Delphi 调试 通过BreakPoint
    折现率”的公式
    考会计证 需要的科目
  • 原文地址:https://www.cnblogs.com/xiaomaLV2/p/2554936.html
Copyright © 2020-2023  润新知