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 shown