Image processing of rice quantity detection based on chain code tracking

Image processing of rice quantity detection based on chain code tracking

// TestProjects.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "bmpFile.h"
#include "FastSobelShenJun.h"
#include "OtsuThre.h"
#include "ChainCode.h"
 
void test_SJ()
{
    
    
	clock_t t1,t2;
	int width,height;

	BYTE *pGryImg=Read8BitBmpFile2Img("..//BmpOrgFile//LDW.bmp",&width,&height);
	BYTE *pResImg=new BYTE [width*height];
	
	t1=clock();
	for(int k=0;k<100;k++)
	ShenJunEdgeFast(pGryImg,width,height,0.3,20,pResImg);
	t2=clock();
	printf("\n%d",t2-t1);
	Write8BitImg2BmpFile(pResImg,width,height,"..//BmpResFile//SJ_03_20.bmp");

	delete pGryImg;
	delete pResImg;

	printf("\nPress any key to exit!");
	getchar();
	getchar();
	return;
}

void test_rice()
{
    
    
	int width,height;

	BYTE *pGryImg=Read8BitBmpFile2Img("..//BmpOrgFile//rice_light_corrected.bmp",&width,&height);
	BYTE *pCodeBuf=new BYTE [width*height];
	BYTE *pResImg=new BYTE [width*height];

	int histogram[256];
	int thre;
	GetHistogram(pGryImg,width,height,histogram);
    thre=GetOtsuThreshold(histogram,256);
	Threshold(pGryImg,width,height,thre);
	Write8BitImg2BmpFile(pGryImg,width,height,"..//BmpResFile//rice_bin.bmp");

	int x,y;
	BYTE *pRow,*pCur;
	int nCode;
	int Area,Perimeter;

	memset(pResImg,0,width*height);
	SetImageBoundary(pGryImg,width,height,0);
	int count = 0;
	for(y=1,pRow=pGryImg+y*width;y<height-1;y++,pRow+=width)
	{
    
    
		for(x=1,pCur=pRow+x;x<width-1;x++,pCur++)
		{
    
    
			if ( (*pCur==255) &&
				 (*(pCur-1)<10)
			   )
			{
    
    
				nCode=TraceContour(pGryImg,width,x,y,pCodeBuf,width*height,true);
				RealAreaAndPerimeter(pCodeBuf,nCode,&Area,&Perimeter);
				if (Area>200)
				{
    
    
					if (Area<300)
					{
    
    
						MarkChainByColor(pResImg,width,x,y,pCodeBuf,nCode,255);
					}
					else
					{
    
    
                        FillingContour(pResImg,width,x,y,pCodeBuf,nCode,true,128,254);
					}
					printf("\narea=%d_perimeter=%d",Area,Perimeter);
					count++;
				}
			}
			else if ( (*pCur==0) &&
				      (*(pCur-1)>250)
			        )
			{
    
    
				nCode=TraceContour(pGryImg,width,x-1,y,pCodeBuf,width*height,false);
			}
		}
	}
	Write8BitImg2BmpFile(pResImg,width,height,"..//BmpResFile//rice_res.bmp");
	
	printf("\ncount=%d", count);

	delete pGryImg;
	delete pCodeBuf;
	delete pResImg;

	printf("\nPress any key to exit!");
	getchar();
	getchar();
	return;
}


#ifdef AAAAAAAAAAAA
struct ContourStruct *GetContours(BYTE *pBinImg,BYTE *pImgBuf,int width,int height,int MiniP,int MiniS,int Out1In2ALL3)
{
    
      
  //   得到所有的轮廓
  int ImgSize,i,y,x,length,Area,Perimeter; 
  BYTE *Chain,*pCode=pImgBuf;
  BYTE *pBin,Cur,Pre;
  struct ContourStruct *Result,*Tail,*NewObj;

    // step.1--------Init
    Result=NULL;
    ImgSize = width*height;
	//step.2--------目标跟踪
	SetImageBoundary(pBinImg,width,height,0); //为了跟踪,必须清0
	for(y=1,pBin=pBinImg+y*width;y<height;y++)
        for(x=0;x<width;x++,pBin++)
		{
    
      Cur=*pBin;
		   Pre=*(pBin-1);
		   if (Cur==Pre) continue;
           // 链码跟踪 
		   length=0;
		   if ((Cur==255)&&(Pre<10)) length=TraceContour(pBinImg,width,x,y,pCode,ImgSize,true);
           else if ((Cur==0)&&(Pre>250)) length=TraceContour(pBinImg,width,x-1,y,pCode,ImgSize,false); 
           // 链码筛选
		   if ( (length==0)||(length<MiniP) ) continue;
		   if ( (Out1In2ALL3==1)&&(Cur==0) ) continue;
		   if ( (Out1In2ALL3==2)&&(Cur==255) ) continue;
		   RealAreaAndPerimeter(pCode,length,&Area,&Perimeter);
		   if ( (Area<MiniS)||(Perimeter<MiniP) ) continue;
		   // 纪录新轮廓
		   Chain=new BYTE [length];
		   if (Chain==NULL) continue;
		   for(i=0;i<length;i++) Chain[i]=pCode[i];
		   NewObj=(struct ContourStruct *) new BYTE [sizeof(struct ContourStruct)];
		   if (NewObj==NULL) {
    
     delete Chain; continue;}
		   if (Cur==255) 
		   {
    
      NewObj->IsOutContour=true;
		      NewObj->x0=x;
		      NewObj->y0=y;
		   }
		   else 
		   {
    
      NewObj->IsOutContour=false;
		      NewObj->x0=x-1;
		      NewObj->y0=y;
		   }
           NewObj->Area = Area;
		   NewObj->Perimeter= Perimeter;
		   NewObj->Left=NewObj->Right=NewObj->Top=NewObj->Bottom=0;
		   NewObj->UsedDown=NewObj->UsedDown=0;
		   NewObj->ChainLength=length;
		   NewObj->Chain=Chain;
		   NewObj->Next=NULL;
		   // 追加
		   if (Result==NULL) Result=Tail=NewObj;
		   else
		   {
    
     Tail->Next=NewObj; 
		     Tail=Tail->Next;
		   }
		}
	// step.3---------return---------------------------//
    //Threshold(pBinImg,width,height,50);
	return Result;
}
#endif

///
//
//     main()
//
///
void main()
{
    
    
	//test_SJ();
	test_rice();
 	return;
}

The result is as shownInsert picture description here
Insert picture description here

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_36587495/article/details/108165428