• 【20160924】GOCVHelper 图像增强部分(1)


       图像增强是图像处理的第一步。这里集成了一些实际使用过程中有用的函数。

      //读取灰度或彩色图片到灰度
        Mat imread2gray(string path){
            Mat src = imread(path);
            Mat srcClone = src.clone();
            if (CV_8UC3 == srcClone.type() )
                cvtColor(srcClone,srcClone,CV_BGR2GRAY);
            return srcClone;
        }
       算法核心在于判断读入图片的通道数,如果是灰度图片则保持;如果是彩色图片则转换为灰度图片。通过这样一个函数,就能够直接获得灰度图片。
     
        //带有上下限的threshold
        Mat threshold2(Mat src,int minvalue,int maxvalue){
            Mat thresh1;
            Mat thresh2;
            Mat dst;
            threshold(src,thresh1,minvalue,255, THRESH_BINARY);
            threshold(src,thresh2,maxvalue,255,THRESH_BINARY_INV);
            dst = thresh1 & thresh2;
            return dst;
        }
        Opencv提供的threshold算法很强大,但是只能够取单门限。这里修改成可以取双门限的形式。
     
        //自适应门限的canny算法 
        //canny2
        Mat canny2(Mat src){
            Mat imagetmp = src.clone();
            double low_thresh = 0.0;  
            double high_thresh = 0.0;  
            AdaptiveFindThreshold(imagetmp,&low_thresh,&high_thresh);
            Canny(imagetmp,imagetmp,low_thresh,high_thresh);   
            return imagetmp;}
        void AdaptiveFindThresholdMat src,double *low,double *high,int aperture_size){
            const int cn = src.channels();
            Mat dx(src.rows,src.cols,CV_16SC(cn));
            Mat dy(src.rows,src.cols,CV_16SC(cn));
            Sobel(src,dx,CV_16S,1,0,aperture_size,1,0,BORDER_REPLICATE);
            Sobel(src,dy,CV_16S,0,1,aperture_size,1,0,BORDER_REPLICATE);
            CvMat _dx = dx;
            CvMat _dy = dy;
            _AdaptiveFindThreshold(&_dx, &_dylowhigh); }  
        void _AdaptiveFindThreshold(CvMat *dxCvMat *dydouble *lowdouble *high){                                                                                
            CvSize size;                                                             
            IplImage *imge=0;                                                        
            int i,j;                                                                 
            CvHistogram *hist;                                                       
            int hist_size = 255;                                                     
            float range_0[]={0,256};                                                 
            floatranges[] = { range_0 };                                           
            double PercentOfPixelsNotEdges = 0.7;                                    
            size = cvGetSize(dx);                                                    
            imge = cvCreateImage(sizeIPL_DEPTH_32F, 1);                            
            // 计算边缘的强度, 并存于图像中                                          
            float maxv = 0;                                                          
            for(i = 0; i < size.heighti++ ){                                                                        
                const short_dx = (short*)(dx->data.ptr + dx->step*i);          
                const short_dy = (short*)(dy->data.ptr + dy->step*i);          
                float_image = (float *)(imge->imageData + imge->widthStep*i);  
                for(j = 0; j < size.widthj++){                                                                
                    _image[j] = (float)(abs(_dx[j]) + abs(_dy[j]));          
                    maxv = maxv < _image[j] ? _image[j]: maxv;}}                                                                        
            if(maxv == 0){                                                           
                *high = 0;                                                       
                *low = 0;                                                        
                cvReleaseImage( &imge );                                         
                return;}                                                                        
            // 计算直方图                                                            
            range_0[1] = maxv;                                                       
            hist_size = (int)(hist_size > maxv ? maxv:hist_size);                    
            hist = cvCreateHist(1, &hist_sizeCV_HIST_ARRAYranges, 1);            
            cvCalcHist( &imgehist, 0, NULL );                                      
            int total = (int)(size.height * size.width * PercentOfPixelsNotEdges);   
            float sum=0;                                                             
            int icount = hist->mat.dim[0].size;                                     
            float *h = (float*)cvPtr1Dhist->bins, 0 );                             
            for(i = 0; i < icounti++){                                                                        
                sum += h[i];                                                     
                ifsum > total )                                                
                    break; }                                                                        
            // 计算高低门限                                                          
            *high = (i+1) * maxv / hist_size ;                                       
            *low = *high * 0.4;                                                      
            cvReleaseImage( &imge );                                                 
            cvReleaseHist(&hist); }     

    // end of canny2
             我们在使用Opencv的canny算法的时候,一般是按照经验填写上下门限值。为了解决这个问题,通过自适应算法(算法来源我想不起来了),自动计算出上下门限。能够取得不错效果。

     
     





  • 相关阅读:
    使用JS实现图片轮播滚动跑马灯效果
    特殊字符和注释标签
    html常用标签总结
    html重点标签总结
    web常用开发工具
    标签分类和关系
    Web标准和骨架
    常用开浏览器内核
    常用浏览器介绍
    2019/08/20记
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/5904319.html
Copyright © 2020-2023  润新知