opencv 抠图联通块(c接口)

#include "stdio.h"
#include "iostream"
#include "opencv/cv.h"
#include "opencv2/opencv.hpp"
#include "basicOCR.h"
#include "time.h"
using namespace std;
using namespace cv;

void ImageRect(IplImage *srcImg, IplImage *dstImg);
int main()
{
    /*basicOCR bor;
    IplImage *image = cvLoadImage("585.pbm",1);
    IplImage *gray = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);
    cvCvtColor(image,gray,CV_RGB2GRAY);
    bor.classify(gray,1);
    //printf("depth = %d\nwidth = %d\nheight = %d\nnChannels = %d\n",image->depth,image->width,image->height,image->nChannels);

    image = cvLoadImage("608.pbm",1);
    cvCvtColor(image,gray,CV_RGB2GRAY);
    bor.classify(gray,1);


    image = cvLoadImage("test002.jpg",1);
    IplImage *gray1 = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);
    cvCvtColor(image,gray1,CV_RGB2GRAY);
    bor.classify(gray1,1);
*/
    basicOCR bor;
    int type;
    while(scanf("%d",&type)!=EOF)
    {    
        if(type == -1)
            break;
    
        char path[20];
        sprintf(path,"./test00%d.jpg",type);
        clock_t start,finish;
        start = clock();
        IplImage *srcImage = cvLoadImage(path,1);
        if(srcImage==NULL){
            printf("%s : path is error...",path);
            continue;
        }

        IplImage *gray2 = cvCreateImage(cvSize(128,128),IPL_DEPTH_8U,1);
        ImageRect(srcImage,gray2);
        //cvCvtColor(srcImage,gray2,CV_RGB2GRAY);
        bor.classify(gray2,1);
        finish = clock();
        double duration = (double)(finish-start)/CLOCKS_PER_SEC;
        printf("检测时间: %f seconds\n",duration);

    }
    return 0;
}
void ImageRect(IplImage *srcImg, IplImage *dstImg)
{
    IplImage *tempImg = cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,1);
    IplImage *resultImg = cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,1);
    IplImage *backgroundImg = cvCreateImage(cvSize(128,128),8,1);
    cvZero(backgroundImg);
    for(int i = 0; i<backgroundImg->height;i++)
    {
        unsigned char *data = (unsigned char*)backgroundImg->imageData+i*backgroundImg->widthStep;
        for(int j=0; j<backgroundImg->width;j++)
        {
            data[j] = 0;
        }
    }
    //cvShowImage("back",backgroundImg);
    cvCvtColor(srcImg,tempImg,CV_RGB2GRAY);
    cvThreshold(tempImg,tempImg,220,255,CV_THRESH_BINARY_INV);
    cvCopy(tempImg,resultImg);
    CvMemStorage *storage = cvCreateMemStorage();
    //cvShowImage("h0",tempImg);
    CvSeq *contours = NULL;
    cvFindContours(tempImg,storage,&contours,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_NONE,cvPoint(0,0));
    int area;
    CvRect rect;
    while(contours)
    {
        rect = cvBoundingRect(contours,0);
        area = rect.width * rect.height;
        if(area>50)
        {
            printf("x");
            //cvRectangle(resultImg,cvPoint(rect.x,rect.y),cvPoint(rect.x+rect.width,rect.y+rect.height),CV_RGB(200,200,200),1,8,0);
            int mHeight = 60;
            int mWidth = 60;
            int mLeft = 40;
            int mTop = 40;
            if(rect.height>rect.width)
            {
                mWidth = (int)(60.0*rect.width/rect.height);
            }else{
                mHeight = (int)(60.0*rect.height/rect.width);
            }
            IplImage *foregroundImg = cvCreateImage(cvSize(mWidth,mHeight),8,1);
            
            cvSetImageROI(resultImg,rect);
            cvSetImageROI(backgroundImg,cvRect(mLeft,mTop,mWidth,mHeight));
            cvResize(resultImg,foregroundImg,CV_INTER_NN);
            cvCopy(foregroundImg,backgroundImg);
            cvResetImageROI(backgroundImg);
            cvResetImageROI(resultImg);
            
            cvReleaseImage(&foregroundImg);
        }
        contours = contours->h_next;
    }
    //cvShowImage("h2",resultImg);
    
    cvThreshold(backgroundImg,backgroundImg,220,255,CV_THRESH_BINARY_INV);
    cvSmooth(backgroundImg,backgroundImg,CV_BLUR,3,3,0,0);
    cvDilate(backgroundImg,backgroundImg,NULL,1);
    cvErode(backgroundImg,backgroundImg,NULL,2);

    cvThreshold(backgroundImg,backgroundImg,220,255,CV_THRESH_BINARY);
    cvCopy(backgroundImg,dstImg,NULL);
    cvSaveImage("./epsq3.jpg",backgroundImg);
    
    //cvShowImage("background",backgroundImg);
    //cvWaitKey(0);
    cvReleaseMemStorage(&storage);
    cvReleaseImage(&tempImg);
    cvReleaseImage(&resultImg);
    cvReleaseImage(&backgroundImg);

}

  

/*#include "stdio.h"
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv2/opencv.hpp"
int main()
{
	
	IplImage *img = cvLoadImage("./paper.jpg",1);

	cvShowImage("showImage",img);
	cvWaitKey(0);
	printf("xx\n");

	return 0;
}*/
#include <stdio.h>  
#include <opencv/highgui.h>  
#include <zbar.h>  
#include <time.h>  
#include <opencv2/opencv.hpp>  
#include <opencv/cv.h>  
#include <iostream>  
   
using namespace std; 
using namespace cv;
using namespace zbar;  
  
#define FLOAT 10  
#define PICTURE "er2.jpg"  
int main(int argc,char *argv[])  
{  
      
    //加载原图  
    IplImage *srcImage = cvLoadImage(PICTURE,1);  
    //cvNamedWindow("1.原图",0);  
    //cvShowImage("1.原图",image);  
  
    //测时  
    clock_t start, finish;  
    double duration;  
    start = clock();  
    //转变为灰度图  
    IplImage *Grayimage = cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U, 1);  
    cvCvtColor(srcImage,Grayimage,CV_BGR2GRAY);  
  
     //cvNamedWindow("Grayimage",0);  
   // cvShowImage("Grayimage",Grayimage);  
  
    //通过sobel来对图片进行竖向边缘检测,输入图像是8位时,输出必须是16位,然后再将图像转变成8位深   
    IplImage *sobel = cvCreateImage(cvGetSize(Grayimage),IPL_DEPTH_16S,1);  
    cvSobel(Grayimage,sobel,2,0,7);  
      
    IplImage *temp = cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1);  
    cvConvertScale(sobel,temp,0.002,0);  
  
    //cvNamedWindow("temp",0);  
    //cvShowImage("temp",temp);  
  
    //对图像进行二值化处理  
    IplImage *threshold = cvCreateImage(cvGetSize(temp),IPL_DEPTH_8U,1);  
    cvThreshold(temp,threshold,13,100,CV_THRESH_BINARY/*| CV_THRESH_OTSU*/);  
     //cvThreshold(temp, threshold, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);   
  
    //cvNamedWindow("threshold",0);  
    //cvShowImage("threshold",threshold);  
  
     //自定义1*3的核进行X方向的膨胀腐蚀    
    IplImage *erode_dilate=cvCreateImage(cvGetSize(threshold),IPL_DEPTH_8U,1);  
    IplConvKernel* kernal = cvCreateStructuringElementEx(3,1, 1, 0, CV_SHAPE_RECT);  
    cvDilate(threshold, erode_dilate, kernal, 15);//X方向膨胀连通数字  
    cvErode(erode_dilate, erode_dilate, kernal, 6);//X方向腐蚀去除碎片  
    cvDilate(erode_dilate, erode_dilate, kernal, 1);//X方向膨胀回复形态  
  
    //自定义3*1的核进行Y方向的膨胀腐蚀  
    kernal = cvCreateStructuringElementEx(1,3, 0, 1, CV_SHAPE_RECT);  
    //cvDilate(erode_dilate, erode_dilate, kernal, 5);  
    cvErode(erode_dilate, erode_dilate, kernal, 2);// Y方向腐蚀去除碎片  
    cvDilate(erode_dilate, erode_dilate, kernal, 6);//回复形态  
  
    //cvNamedWindow("erode_dilate",0);  
    //cvShowImage("erode_dilate",erode_dilate);  
  
    //图形检测  
    IplImage* copy = cvCloneImage(erode_dilate);//直接把erode_dilate的数据复制给copy  
    IplImage* copy1 = cvCloneImage(srcImage);//直接把image的数据复制给copy1  
    CvMemStorage* storage = cvCreateMemStorage();  
    CvSeq* contours;  
    cvFindContours(copy, storage, &contours);  
    int i=0,k=0,j=0;  
    CvRect RECT[100];  
    CvRect Rect[100];  
      
    while(contours != NULL)  
    {  
        //绘制轮廓的最小外接矩形,如果满足条件,将该矩形绘制在显示图片dst  
        /* 
           矩形要求: 
               1.宽度与高度的比值在(2,5)之间 
               2.面积大于图像的 1/20000 
               3.y轴的位置在图像高度减去50以下 
        */  
        CvRect rect=cvBoundingRect( contours, 1 );  //cvBoundingRect计算点集的最外面(up-right)矩形边界。  
        if(rect.width/rect.height>0.8  
            &&rect.width/rect.height<1.2  
            &&rect.height*rect.height*FLOAT>copy1->height*copy1->width  
            &&rect.y<copy1->height-50  
            )  
        {  
            printf("rect.x = %d  rect.y = %d  rect.width = %d  rect.height = %d\n",rect.x,rect.y,rect.width,rect.height);  
            //rect.x-=10;  
           // rect.y-=10;  
           // rect.width+=20;  
           // rect.height+=20;  
            RECT[i]=rect; //将图片中符合的矩形区域存到RECT  
            i++;  
        }  
                contours= contours->h_next;  
          
    }  
    printf("Find the rect %d!\n",i);  
    for(j=0;j<i;j++)  
    {  
        if(j==0)  
        {  
            cvRectangleR(copy1,RECT[j],CV_RGB(255,0,0),3);  
            Rect[k]=RECT[j];  
            k++;  
            //printf("j = %d\n",j);  
            //printf("The j is the %d!\n",j);  
        }  
        else if(RECT[j-1].y-RECT[j].y>100  
                ||(RECT[j-1].x-RECT[j].x>200  
                ||RECT[j].x-RECT[j-1].x>200))  
        {  
              cvRectangleR(copy1,RECT[j],CV_RGB(255,0,0),3);  
              Rect[k]=RECT[j];  
              k++;  
              //printf("The jj is the %d!\n",j);  
        }  
    }  
      
    cvNamedWindow("copy1",0);  
    cvShowImage("copy1",copy1);  
    //cvWaitKey(0);  
    //cvReleaseImage(&Grayimage);  
    cvReleaseImage(&temp);  
    cvReleaseImage(&threshold);  
    cvReleaseImage(&erode_dilate);  
    cvReleaseImage(&srcImage);  
    cvReleaseImage(&copy);  
    cvReleaseImage(&copy1);  
    // create a reader  
    //srcImage = cvLoadImage(PICTURE,1);  
    srcImage = Grayimage;//解码图片必需位灰度图  
    ImageScanner scanner;  
  
    // configure the reader  
    scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);  
  
    // obtain image data  
       
    const void *raw = NULL;  
    //int width=srcImage->width;    
    //int height=srcImage->height;     
    //raw = srcImage->imageDataOrigin;  
    //cvMat(int rows, int cols, int type, void * data CV_DEFAULT(NULL))  
    //cout<<"The number is the one!"<<endl;  
    Mat im(srcImage, TRUE);  
    int width=im.cols;    
    int height=im.rows;     
    raw = im.data;  
    // wrap image data  
    zbar::Image image(width, height, "Y800", raw, width * height);  
  
    // scan the image for barcodes  
    int n = scanner.scan(image);  
     
    std::string strTemp="";  
    // extract results  
     //cout<<"The number is the two!"<<endl;  
    zbar::Image::SymbolIterator symbol = image.symbol_begin();  
    //cout<<"The number is the three!"<<endl;  
    cout << "decoded " << symbol->get_type_name()<<endl;  
      
    for(;symbol != image.symbol_end();++symbol)   
    {  
            // do something useful with results  
               
            strTemp =strTemp +symbol->get_data()+";";  
            cout << "decoded " << symbol->get_type_name()<< " symbol \"" << symbol->get_data() << '"' << endl;  
    }  
  
    // clean up  
    image.set_data(NULL, 0);  
      
    cvWaitKey(0);  
    cvReleaseImage(&Grayimage);  
        return(0);  
}  

  

posted @ 2016-12-15 18:17  一样菜  阅读(1929)  评论(0编辑  收藏  举报