笔迹鉴别程序
考试的笔迹鉴别程序,分辨出不同人写的笔迹
This commit is contained in:
22
测试/本机测试/2-侯-算法/handwriting.sln
Normal file
22
测试/本机测试/2-侯-算法/handwriting.sln
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30501.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "handwriting", "handwriting\handwriting.vcxproj", "{4A0EA5CA-C4D6-4A83-9201-B683D6FAEBD5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4A0EA5CA-C4D6-4A83-9201-B683D6FAEBD5}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4A0EA5CA-C4D6-4A83-9201-B683D6FAEBD5}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4A0EA5CA-C4D6-4A83-9201-B683D6FAEBD5}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4A0EA5CA-C4D6-4A83-9201-B683D6FAEBD5}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
54
测试/本机测试/2-侯-算法/handwriting/Cjbsb.cpp
Normal file
54
测试/本机测试/2-侯-算法/handwriting/Cjbsb.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 程序名:Cjbsb.c
|
||||
功能:读入图像文件,甄别图像的角标
|
||||
*/
|
||||
#pragma once
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern IplImage* src;
|
||||
|
||||
IplImage* Cjbsb(IplImage* img,IplImage* imgjbsb,int jbwhite,int jbblack)
|
||||
{
|
||||
/*定义变量*/
|
||||
int i,j,ii,jj,sumjb1,sumjb2,jbi=0,jbj=0;
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
int brklab=0;
|
||||
/* 获取图像信息*/
|
||||
height = img->height;
|
||||
width = img->width;
|
||||
step = img->widthStep;
|
||||
channels = img->nChannels;
|
||||
data = (uchar *)img->imageData;
|
||||
|
||||
// IplImage* imgjbsb = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
|
||||
cvCopy(img,imgjbsb,NULL);
|
||||
uchar *imgjbsbdata= (uchar *)imgjbsb->imageData;
|
||||
|
||||
|
||||
|
||||
|
||||
//以角标为起点进行裁剪与画框
|
||||
CvSize jbcjsize=cvSize(835,165); //角标裁剪框的大小,宽为835象素,高为165象素
|
||||
IplImage* imgjbcj = cvCreateImage(jbcjsize,img->depth,img->nChannels);
|
||||
uchar *imgjbcjdata= (uchar *)imgjbcj->imageData;
|
||||
int jbcjstep = imgjbcj->widthStep;
|
||||
int jbcjchannels = imgjbcj->nChannels;
|
||||
for(i=0;i<165;i++)
|
||||
for(j=0;j<835;j++)
|
||||
imgjbcjdata[i*jbcjstep+j*jbcjchannels]=data[(i+jbi)*step+(j+jbj)*channels];
|
||||
for(i=0;i<165;i=i+2)
|
||||
{
|
||||
imgjbsbdata[(i+jbi)*step+jbj*channels]=0;
|
||||
imgjbsbdata[(i+jbi)*step+(jbj+835)*channels]=0;
|
||||
}
|
||||
for(j=0;j<835;j=j+2)
|
||||
{
|
||||
imgjbsbdata[jbi*step+(j+jbj)*channels]=0;
|
||||
imgjbsbdata[(jbi+165)*step+(j+jbj)*channels]=0;
|
||||
}
|
||||
|
||||
return imgjbcj;
|
||||
}
|
||||
0
测试/本机测试/2-侯-算法/handwriting/Cword.cpp
Normal file
0
测试/本机测试/2-侯-算法/handwriting/Cword.cpp
Normal file
11
测试/本机测试/2-侯-算法/handwriting/Cword.h
Normal file
11
测试/本机测试/2-侯-算法/handwriting/Cword.h
Normal file
@@ -0,0 +1,11 @@
|
||||
class Cword{
|
||||
private:
|
||||
|
||||
public:
|
||||
Point wbegin;
|
||||
Point wend;
|
||||
// int n; //在总个数中的位置
|
||||
int nn; //在文字中的序号
|
||||
bool isword; //是否为文字
|
||||
int blacknum; //本文字中的黑色像素数
|
||||
};
|
||||
29
测试/本机测试/2-侯-算法/handwriting/Integral.cpp
Normal file
29
测试/本机测试/2-侯-算法/handwriting/Integral.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
IplImage* Integral(IplImage* img, int width, int height)
|
||||
{
|
||||
unsigned long *columnSum = new unsigned long[width]; // sum of each column
|
||||
// calculate integral of the first line
|
||||
for(int i=0;i<width;i++)
|
||||
{
|
||||
columnSum[i]=inputMatrix[i];
|
||||
outputMatrix[i] = inputMatrix[i];
|
||||
if(i>0)
|
||||
{
|
||||
outputMatrix[i] += outputMatrix[i-1];
|
||||
}
|
||||
}
|
||||
for (int i=1;i<height;i++)
|
||||
{
|
||||
int offset = i*width;
|
||||
// first column of each line
|
||||
columnSum[0] +=inputMatrix[offset];
|
||||
outputMatrix[offset] = columnSum[0];
|
||||
// other columns
|
||||
for(int j=1;j<width;j++)
|
||||
{
|
||||
columnSum[j] += inputMatrix[offset+j];
|
||||
outputMatrix[offset+j] = outputMatrix[offset+j-1] + columnSum[j];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} */
|
||||
9
测试/本机测试/2-侯-算法/handwriting/Point.h
Normal file
9
测试/本机测试/2-侯-算法/handwriting/Point.h
Normal file
@@ -0,0 +1,9 @@
|
||||
class Point{
|
||||
private:
|
||||
|
||||
public:
|
||||
int x;
|
||||
int y;
|
||||
|
||||
void setpoint(int a,int b){x=a;y=b;}
|
||||
};
|
||||
683
测试/本机测试/2-侯-算法/handwriting/Thinner.cpp
Normal file
683
测试/本机测试/2-侯-算法/handwriting/Thinner.cpp
Normal file
@@ -0,0 +1,683 @@
|
||||
//**************************************************************************
|
||||
//Thinner.cpp
|
||||
//细化算法实现文件
|
||||
//**************************************************************************
|
||||
//#include "StdAfx.h"
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include "Thinner.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void beforethin(unsigned char *ip, unsigned char *jp, unsigned long lx, unsigned long ly){
|
||||
//void beforethin(char *ip, char *jp, unsigned long lx, unsigned long ly)
|
||||
unsigned long i,j;
|
||||
for(i=0; i<ly; i++){
|
||||
for(j=0; j<lx; j++){
|
||||
//这里要视前景是白点还是黑点而定,可以改动
|
||||
//如果前景是白点,就是这样;反之反过来
|
||||
//jp[i*lx+j]=ip[i*lx+j];
|
||||
/* jp[i*lx+j]=255;*/
|
||||
if(ip[i*lx+j]>0)
|
||||
jp[i*lx+j]=0;
|
||||
else
|
||||
jp[i*lx+j]=255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//Hilditch细化算法
|
||||
//功能:对图象进行细化
|
||||
//参数:image:代表图象的一维数组
|
||||
// lx:图象宽度
|
||||
// ly:图象高度
|
||||
// 无返回值
|
||||
void ThinnerHilditch(void *image, unsigned long lx, unsigned long ly){
|
||||
char *f, *g;
|
||||
char n[10];
|
||||
unsigned int counter;
|
||||
short k, shori, xx, nrn;
|
||||
unsigned long i, j;
|
||||
long kk, kk11, kk12, kk13, kk21, kk22, kk23, kk31, kk32, kk33, size;
|
||||
size = (long)lx * (long)ly;
|
||||
g = (char *)malloc(size);
|
||||
|
||||
if(g == NULL){
|
||||
printf("error in allocating memory!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
f = (char *)image;
|
||||
for(i=0; i<lx; i++){
|
||||
for(j=0; j<ly; j++){
|
||||
kk=i*ly+j;
|
||||
if(f[kk]!=0){
|
||||
f[kk]=1;
|
||||
g[kk]=f[kk];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
counter = 1;
|
||||
|
||||
do{
|
||||
printf("%4d*",counter);
|
||||
counter++;
|
||||
shori = 0;
|
||||
|
||||
for(i=0; i<lx; i++){
|
||||
for(j=0; j<ly; j++){
|
||||
kk = i*ly+j;
|
||||
if(f[kk]<0)
|
||||
f[kk] = 0;
|
||||
g[kk]= f[kk];
|
||||
}
|
||||
}
|
||||
|
||||
for(i=1; i<lx-1; i++){
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk=i*ly+j;
|
||||
|
||||
if(f[kk]!=1)
|
||||
continue;
|
||||
|
||||
kk11 = (i-1)*ly+j-1;
|
||||
kk12 = kk11 + 1;
|
||||
kk13 = kk12 + 1;
|
||||
kk21 = i*ly+j-1;
|
||||
kk22 = kk21 + 1;
|
||||
kk23 = kk22 + 1;
|
||||
kk31 = (i+1)*ly+j-1;
|
||||
kk32 = kk31 + 1;
|
||||
kk33 = kk32 + 1;
|
||||
|
||||
if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])!=0)
|
||||
continue;
|
||||
|
||||
nrn = g[kk11] + g[kk12] + g[kk13] + g[kk21] + g[kk23] +
|
||||
g[kk31] + g[kk32] + g[kk33];
|
||||
|
||||
if(nrn <= 1){
|
||||
f[kk22] = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
n[4] = f[kk11];
|
||||
n[3] = f[kk12];
|
||||
n[2] = f[kk13];
|
||||
n[5] = f[kk21];
|
||||
n[1] = f[kk23];
|
||||
n[6] = f[kk31];
|
||||
n[7] = f[kk32];
|
||||
n[8] = f[kk33];
|
||||
n[9] = n[1];
|
||||
xx = 0;
|
||||
|
||||
for(k=1; k<8; k=k+2){
|
||||
if((!n[k])&&(n[k+1]||n[k+2]))
|
||||
xx++;
|
||||
}
|
||||
|
||||
if(xx!=1){
|
||||
f[kk22] = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(f[kk12] == -1){
|
||||
f[kk12] = 0;
|
||||
n[3] = 0;
|
||||
xx = 0;
|
||||
|
||||
for(k=1; k<8; k=k+2){
|
||||
if((!n[k])&&(n[k+1]||n[k+2]))
|
||||
xx++;
|
||||
}
|
||||
|
||||
if(xx != 1){
|
||||
f[kk12] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
f[kk12] = -1;
|
||||
n[3] = -1;
|
||||
}
|
||||
|
||||
if(f[kk21]!=-1){
|
||||
f[kk22] = -1;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
f[kk21] = 0;
|
||||
n[5] = 0;
|
||||
xx = 0;
|
||||
|
||||
for(k=1; k<8; k=k+2){
|
||||
if((!n[k])&&(n[k+1]||n[k+2])){
|
||||
xx++;
|
||||
}
|
||||
}
|
||||
|
||||
if(xx == 1){
|
||||
f[kk21] = -1;
|
||||
f[kk22] = -1;
|
||||
shori =1;
|
||||
}
|
||||
else
|
||||
f[kk21] = -1;
|
||||
}
|
||||
}
|
||||
}while(shori);
|
||||
|
||||
free(g);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//Pavlidis细化算法
|
||||
//功能:对图象进行细化
|
||||
//参数:image:代表图象的一维数组
|
||||
// lx:图象宽度
|
||||
// ly:图象高度
|
||||
// 无返回值
|
||||
void ThinnerPavlidis(void *image, unsigned long lx, unsigned long ly){
|
||||
char erase, n[8];
|
||||
char *f;
|
||||
unsigned char bdr1,bdr2,bdr4,bdr5;
|
||||
short c,k,b;
|
||||
unsigned long i,j;
|
||||
long kk,kk1,kk2,kk3;
|
||||
f = (char*)image;
|
||||
|
||||
for(i=1; i<lx-1; i++){
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk = i*ly + j;
|
||||
if(f[kk])
|
||||
f[kk] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0, kk1=0, kk2=ly-1; i<lx; i++, kk1+=ly, kk2+=ly){
|
||||
f[kk1]=0;
|
||||
f[kk2]=0;
|
||||
}
|
||||
|
||||
for(j=0, kk=(lx-1)*ly; j<ly; j++,kk++){
|
||||
f[j]=0;
|
||||
f[kk]=0;
|
||||
}
|
||||
|
||||
c=5;
|
||||
erase =1;
|
||||
while(erase){
|
||||
c++;
|
||||
for(i=1; i<lx-1; i++){
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk=i*ly+j;
|
||||
if(f[kk]!=1)
|
||||
continue;
|
||||
|
||||
kk1 = kk-ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[3] = f[kk1];
|
||||
n[2] = f[kk2];
|
||||
n[1] = f[kk3];
|
||||
kk1 = kk - 1;
|
||||
kk3 = kk + 1;
|
||||
n[4] = f[kk1];
|
||||
n[0] = f[kk3];
|
||||
kk1 = kk + ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[5] = f[kk1];
|
||||
n[6] = f[kk2];
|
||||
n[7] = f[kk3];
|
||||
|
||||
bdr1 =0;
|
||||
for(k=0; k<8; k++){
|
||||
if(n[k]>=1)
|
||||
bdr1|=0x80>>k;
|
||||
}
|
||||
|
||||
if((bdr1&0252)== 0252)
|
||||
continue;
|
||||
f[kk] = 2;
|
||||
b=0;
|
||||
|
||||
for(k=0; k<=7; k++){
|
||||
b+=bdr1&(0x80>>k);
|
||||
}
|
||||
|
||||
if(b<=1)
|
||||
f[kk]=3;
|
||||
|
||||
if((bdr1&0160)!=0&&(bdr1&07)!=0&&(bdr1&0210)==0)
|
||||
f[kk]=3;
|
||||
else if((bdr1&&0301)!=0&&(bdr1&034)!=0&&(bdr1&042)==0)
|
||||
f[kk]=3;
|
||||
else if((bdr1&0202)==0 && (bdr1&01)!=0)
|
||||
f[kk]=3;
|
||||
else if((bdr1&0240)==0 && (bdr1&0100)!=0)
|
||||
f[kk]=3;
|
||||
else if((bdr1&050)==0 && (bdr1&020)!=0)
|
||||
f[kk]=3;
|
||||
else if((bdr1&012)==0 && (bdr1&04)!=0)
|
||||
f[kk]=3;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=1; i<lx-1; i++){
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk = i*ly + j;
|
||||
if(!f[kk])
|
||||
continue;
|
||||
|
||||
kk1 = kk - ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[3] = f[kk1];
|
||||
n[2] = f[kk2];
|
||||
n[1] = f[kk3];
|
||||
kk1 = kk - 1;
|
||||
kk2 = kk + 1;
|
||||
n[4] = f[kk1];
|
||||
n[0] = f[kk3];
|
||||
kk1 = kk + ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[5] = f[kk1];
|
||||
n[6] = f[kk2];
|
||||
n[7] = f[kk3];
|
||||
bdr1 = bdr2 =0;
|
||||
|
||||
for(k=0; k<=7; k++){
|
||||
if(n[k]>=1)
|
||||
bdr1|=0x80>>k;
|
||||
if(n[k]>=2)
|
||||
bdr2|=0x80>>k;
|
||||
}
|
||||
|
||||
if(bdr1==bdr2){
|
||||
f[kk] = 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(f[kk]!=2)
|
||||
continue;
|
||||
|
||||
if((bdr2&0200)!=0 && (bdr1&010)==0 &&((bdr1&0100)!=0 &&(bdr1&001)!=0 ||
|
||||
((bdr1&0100)!=0 ||(bdr1 & 001)!=0) && (bdr1&060)!=0 &&(bdr1&06)!=0)){
|
||||
f[kk] = 4;
|
||||
}
|
||||
|
||||
else if((bdr2&040)!=0 && (bdr1&02)==0 && ((bdr1&020)!=0 && (bdr1&0100)!=0 ||
|
||||
((bdr1&020)!=0 || (bdr1&0100)!=0) && (bdr1&014)!=0 && (bdr1&0201)!=0)){
|
||||
f[kk] = 4;
|
||||
}
|
||||
|
||||
else if((bdr2&010)!=0 && (bdr1&0200)==0 && ((bdr1&04)!=0 && (bdr1&020)!=0 ||
|
||||
((bdr1&04)!=0 || (bdr1&020)!=0) && (bdr1&03)!=0 && (bdr1&0140)!=0)){
|
||||
f[kk] = 4;
|
||||
}
|
||||
|
||||
else if((bdr2&02)!=0 && (bdr1&040)==0 && ((bdr1&01)!=0 && (bdr1&04)!=0 ||
|
||||
((bdr1&01)!=0 || (bdr1&04)!=0) && (bdr1&0300)!=0 && (bdr1&030)!=0)){
|
||||
f[kk] = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=1; i<lx-1; i++){
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk = i*ly + j;
|
||||
if(f[kk]!=2)
|
||||
continue;
|
||||
kk1 = kk - ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[3] = f[kk1];
|
||||
n[2] = f[kk2];
|
||||
n[1] = f[kk3];
|
||||
kk1 = kk - 1;
|
||||
kk2 = kk + 1;
|
||||
n[4] = f[kk1];
|
||||
n[0] = f[kk3];
|
||||
kk1 = kk + ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[5] = f[kk1];
|
||||
n[6] = f[kk2];
|
||||
n[7] = f[kk3];
|
||||
bdr4 = bdr5 =0;
|
||||
for(k=0; k<=7; k++){
|
||||
if(n[k]>=4)
|
||||
bdr4|=0x80>>k;
|
||||
if(n[k]>=5)
|
||||
bdr5|=0x80>>k;
|
||||
}
|
||||
if((bdr4&010) == 0){
|
||||
f[kk] = 5;
|
||||
continue;
|
||||
}
|
||||
if((bdr4&040) == 0 && bdr5 ==0){
|
||||
f[kk] = 5;
|
||||
continue;
|
||||
}
|
||||
if(f[kk]==3||f[kk]==4)
|
||||
f[kk] = c;
|
||||
}
|
||||
}
|
||||
|
||||
erase = 0;
|
||||
for(i=1; i<lx-1; i++){
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk = i*ly +j;
|
||||
if(f[kk]==2||f[kk] == 5){
|
||||
erase = 1;
|
||||
f[kk] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//Rosenfeld细化算法
|
||||
//功能:对图象进行细化
|
||||
//参数:image:代表图象的一维数组
|
||||
// lx:图象宽度
|
||||
// ly:图象高度
|
||||
// 无返回值
|
||||
void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly){
|
||||
char *f, *g;
|
||||
char n[10];
|
||||
char a[5] = {0, -1, 1, 0, 0};
|
||||
char b[5] = {0, 0, 0, 1, -1};
|
||||
char nrnd, cond, n48, n26, n24, n46, n68, n82, n123, n345, n567, n781;
|
||||
short k, shori;
|
||||
unsigned long i, j;
|
||||
long ii, jj, kk, kk1, kk2, kk3, size;
|
||||
size = (long)lx * (long)ly;
|
||||
|
||||
g = (char *)malloc(size);
|
||||
if(g==NULL){
|
||||
printf("error in alocating mmeory!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
f = (char *)image;
|
||||
for(kk=0l; kk<size; kk++){
|
||||
g[kk] = f[kk];
|
||||
}
|
||||
|
||||
do{
|
||||
shori = 0;
|
||||
for(k=1; k<=4; k++){
|
||||
for(i=1; i<lx-1; i++){
|
||||
ii = i + a[k];
|
||||
|
||||
for(j=1; j<ly-1; j++){
|
||||
kk = i*ly + j;
|
||||
|
||||
if(!f[kk])
|
||||
continue;
|
||||
|
||||
jj = j + b[k];
|
||||
kk1 = ii*ly + jj;
|
||||
|
||||
if(f[kk1])
|
||||
continue;
|
||||
|
||||
kk1 = kk - ly -1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[3] = f[kk1];
|
||||
n[2] = f[kk2];
|
||||
n[1] = f[kk3];
|
||||
kk1 = kk - 1;
|
||||
kk3 = kk + 1;
|
||||
n[4] = f[kk1];
|
||||
n[8] = f[kk3];
|
||||
kk1 = kk + ly - 1;
|
||||
kk2 = kk1 + 1;
|
||||
kk3 = kk2 + 1;
|
||||
n[5] = f[kk1];
|
||||
n[6] = f[kk2];
|
||||
n[7] = f[kk3];
|
||||
|
||||
nrnd = n[1] + n[2] + n[3] + n[4]
|
||||
+n[5] + n[6] + n[7] + n[8];
|
||||
if(nrnd<=1)
|
||||
continue;
|
||||
|
||||
cond = 0;
|
||||
n48 = n[4] + n[8];
|
||||
n26 = n[2] + n[6];
|
||||
n24 = n[2] + n[4];
|
||||
n46 = n[4] + n[6];
|
||||
n68 = n[6] + n[8];
|
||||
n82 = n[8] + n[2];
|
||||
n123 = n[1] + n[2] + n[3];
|
||||
n345 = n[3] + n[4] + n[5];
|
||||
n567 = n[5] + n[6] + n[7];
|
||||
n781 = n[7] + n[8] + n[1];
|
||||
|
||||
if(n[2]==1 && n48==0 && n567>0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[6]==1 && n48==0 && n123>0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[8]==1 && n26==0 && n345>0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[4]==1 && n26==0 && n781>0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[5]==1 && n46==0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[7]==1 && n68==0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[1]==1 && n82==0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(n[3]==1 && n24==0){
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
cond = 1;
|
||||
if(!cond)
|
||||
continue;
|
||||
g[kk] = 0;
|
||||
shori = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<lx; i++){
|
||||
for(j=0; j<ly; j++){
|
||||
kk = i*ly + j;
|
||||
f[kk] = g[kk];
|
||||
}
|
||||
}
|
||||
}
|
||||
}while(shori);
|
||||
|
||||
free(g);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//基于索引表的细化细化算法
|
||||
//功能:对图象进行细化
|
||||
//参数:lpDIBBits:代表图象的一维数组
|
||||
// lWidth:图象高度
|
||||
// lHeight:图象宽度
|
||||
// 无返回值
|
||||
|
||||
/*
|
||||
BOOL WINAPI ThiningDIBSkeleton (LPSTR lpDIBBits, LONG lWidth, LONG lHeight){
|
||||
//循环变量
|
||||
long i;
|
||||
long j;
|
||||
long lLength;
|
||||
|
||||
unsigned char deletemark[256] = {
|
||||
0,0,0,0,0,0,0,1, 0,0,1,1,0,0,1,1,
|
||||
0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,1,
|
||||
0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,
|
||||
0,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,
|
||||
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,
|
||||
1,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,
|
||||
0,0,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,
|
||||
0,0,0,0,0,0,0,0, 0,0,0,1,0,0,1,1,
|
||||
1,1,0,1,0,0,0,1, 0,0,0,0,0,0,0,0,
|
||||
1,1,0,1,0,0,0,1, 1,1,0,0,1,0,0,0,
|
||||
0,1,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,
|
||||
0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,1,
|
||||
1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0,
|
||||
1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0
|
||||
};//索引表
|
||||
|
||||
unsigned char p0, p1, p2, p3, p4, p5, p6, p7;
|
||||
unsigned char *pmid, *pmidtemp;
|
||||
unsigned char sum;
|
||||
int changed;
|
||||
bool bStart = true;
|
||||
lLength = lWidth * lHeight;
|
||||
unsigned char *pTemp = (unsigned char *)malloc(sizeof(unsigned char) * lWidth * lHeight);
|
||||
|
||||
// P0 P1 P2
|
||||
// P7 P3
|
||||
// P6 P5 P4
|
||||
|
||||
while(bStart){
|
||||
bStart = false;
|
||||
changed = 0;
|
||||
|
||||
//首先求边缘点(并行)
|
||||
pmid = (unsigned char *)lpDIBBits + lWidth + 1;
|
||||
memset(pTemp, (BYTE) 0, lLength);
|
||||
pmidtemp = (unsigned char *)pTemp + lWidth + 1;
|
||||
for(i = 1; i < lHeight -1; i++){
|
||||
for(j = 1; j < lWidth - 1; j++){
|
||||
if( *pmid == 0){
|
||||
pmid++;
|
||||
pmidtemp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
p3 = *(pmid + 1);
|
||||
p2 = *(pmid + 1 - lWidth);
|
||||
p1 = *(pmid - lWidth);
|
||||
p0 = *(pmid - lWidth -1);
|
||||
p7 = *(pmid - 1);
|
||||
p6 = *(pmid + lWidth - 1);
|
||||
p5 = *(pmid + lWidth);
|
||||
p4 = *(pmid + lWidth + 1);
|
||||
|
||||
sum = p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7;
|
||||
if(sum == 0){
|
||||
*pmidtemp = 1;
|
||||
}
|
||||
|
||||
pmid++;
|
||||
pmidtemp++;
|
||||
}
|
||||
pmid++;
|
||||
pmid++;
|
||||
pmidtemp++;
|
||||
pmidtemp++;
|
||||
}
|
||||
|
||||
//现在开始串行删除
|
||||
pmid = (unsigned char *)lpDIBBits + lWidth + 1;
|
||||
pmidtemp = (unsigned char *)pTemp + lWidth + 1;
|
||||
|
||||
for(i = 1; i < lHeight -1; i++){
|
||||
for(j = 1; j < lWidth - 1; j++){
|
||||
if( *pmidtemp == 0){
|
||||
pmid++;
|
||||
pmidtemp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
p3 = *(pmid + 1);
|
||||
p2 = *(pmid + 1 - lWidth);
|
||||
p1 = *(pmid - lWidth);
|
||||
p0 = *(pmid - lWidth -1);
|
||||
p7 = *(pmid - 1);
|
||||
p6 = *(pmid + lWidth - 1);
|
||||
p5 = *(pmid + lWidth);
|
||||
p4 = *(pmid + lWidth + 1);
|
||||
|
||||
p1 *= 2;
|
||||
p2 *= 4;
|
||||
p3 *= 8;
|
||||
p4 *= 16;
|
||||
p5 *= 32;
|
||||
p6 *= 64;
|
||||
p7 *= 128;
|
||||
|
||||
sum = p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7;
|
||||
if(deletemark[sum] == 1){
|
||||
*pmid = 0;
|
||||
bStart = true;
|
||||
}
|
||||
|
||||
pmid++;
|
||||
pmidtemp++;
|
||||
}
|
||||
|
||||
pmid++;
|
||||
pmid++;
|
||||
pmidtemp++;
|
||||
pmidtemp++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
11
测试/本机测试/2-侯-算法/handwriting/Thinner.h
Normal file
11
测试/本机测试/2-侯-算法/handwriting/Thinner.h
Normal file
@@ -0,0 +1,11 @@
|
||||
//***************************************************************************
|
||||
// 文件:Thinner.h
|
||||
// 功能:四种不同的细化算法
|
||||
//***************************************************************************
|
||||
|
||||
void beforethin(unsigned char *ip,unsigned char *jp, unsigned long lx, unsigned long ly);
|
||||
void ThinnerHilditch(void *image, unsigned long lx, unsigned long ly);
|
||||
void ThinnerPavlidis(void *image, unsigned long lx, unsigned long ly);
|
||||
void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly);
|
||||
//注意该函数lWidth应该是Height;
|
||||
//BOOL WINAPI ThiningDIBSkeleton (LPSTR lpDIBBits, LONG lWidth, LONG lHeight);
|
||||
47
测试/本机测试/2-侯-算法/handwriting/binary.cpp
Normal file
47
测试/本机测试/2-侯-算法/handwriting/binary.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 程序名:binary.c
|
||||
功能:读入图像文件,进行二值化
|
||||
*/
|
||||
#pragma once
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
int* binary(IplImage* img,int bithro)
|
||||
{
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
int i,j;
|
||||
static int black[1000]; //C语言不提倡返回一个局部变量的地址以外的功能,所以你必须定义的局部变量,如静态变量。
|
||||
/* 获取图像信息*/
|
||||
height = img->height;
|
||||
width = img->width;
|
||||
step = img->widthStep;
|
||||
channels = img->nChannels;
|
||||
data = (uchar *)img->imageData;
|
||||
|
||||
/*二值化,并统计黑像素的个数*/
|
||||
for(i=0;i<height;i++)
|
||||
{
|
||||
for(j=0;j<width;j++)//对图像每个点进行二值化,原值为128
|
||||
data[i*step+j*channels]=(data[i*step+j*channels]>bithro)?255:0;
|
||||
}
|
||||
|
||||
/*计算每一行的黑像素个数*/
|
||||
int tempBlackPixel=0;
|
||||
|
||||
memset(black,0,1000); //##初始化内存,这里用做清零black数组
|
||||
for(i=height-1;i>0;i--)
|
||||
{
|
||||
for(int j=0;j<width;j++)
|
||||
{
|
||||
if(data[i*step+j*channels]==0) //计算黑色的像素数
|
||||
tempBlackPixel+=1;
|
||||
}
|
||||
black[height-i]=tempBlackPixel; //black记录黑色像素数
|
||||
tempBlackPixel=0;
|
||||
}
|
||||
//二值化,并统计黑像素的个数**********
|
||||
return black;
|
||||
}
|
||||
|
||||
|
||||
14
测试/本机测试/2-侯-算法/handwriting/binary2.cpp
Normal file
14
测试/本机测试/2-侯-算法/handwriting/binary2.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
//图像的二值化
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
int* Binary2(IplImage *g_pGrayImage,int bithro)
|
||||
{
|
||||
IplImage *g_pBinaryImage = NULL;
|
||||
// 转为二值图
|
||||
cvThreshold(g_pGrayImage, g_pBinaryImage, bithro, 255, CV_THRESH_BINARY);
|
||||
cvCopy(g_pGrayImage, g_pBinaryImage,NULL);
|
||||
return 0;
|
||||
}
|
||||
39
测试/本机测试/2-侯-算法/handwriting/getFiles.cpp
Normal file
39
测试/本机测试/2-侯-算法/handwriting/getFiles.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 程序名:getFiles.c
|
||||
功能:返回一个文件夹下的所有文件名
|
||||
*/
|
||||
#pragma once
|
||||
#include<io.h>
|
||||
#include <stdio.h>
|
||||
#include<vector>
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
|
||||
void getFiles(string path, vector<string>& files ){
|
||||
using namespace std;//引入整个名空间
|
||||
//文件句柄
|
||||
long hFile = 0;
|
||||
//文件信息
|
||||
struct _finddata_t fileinfo;
|
||||
string p;
|
||||
if((hFile = _findfirst(p.assign(path).append("/*").c_str(),&fileinfo)) != -1)
|
||||
{
|
||||
do
|
||||
{
|
||||
//如果是目录,迭代之
|
||||
|
||||
if((fileinfo.attrib & _A_SUBDIR))
|
||||
{
|
||||
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
|
||||
getFiles( p.assign(path).append("/").append(fileinfo.name), files );
|
||||
} //如果不是,加入列表
|
||||
else
|
||||
{
|
||||
files.push_back(p.assign(path).append("/").append(fileinfo.name) );
|
||||
// cout<<fileinfo.name<<endl;
|
||||
}
|
||||
}while(_findnext(hFile, &fileinfo) == 0);
|
||||
|
||||
_findclose(hFile);
|
||||
}
|
||||
}
|
||||
39
测试/本机测试/2-侯-算法/handwriting/getFolders.cpp
Normal file
39
测试/本机测试/2-侯-算法/handwriting/getFolders.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 程序名:getFolders.c
|
||||
功能:返回一个文件夹下的所有文件夹的名称
|
||||
*/
|
||||
#pragma once
|
||||
#include<io.h>
|
||||
#include <stdio.h>
|
||||
#include<vector>
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
|
||||
int getFolders(string path, vector<string>& files )
|
||||
{
|
||||
using namespace std;//引入整个名空间
|
||||
//文件句柄
|
||||
long hFile = 0;
|
||||
//文件信息
|
||||
struct _finddata_t fileinfo;
|
||||
string p;
|
||||
|
||||
|
||||
int i=0;
|
||||
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1)
|
||||
{
|
||||
do
|
||||
{
|
||||
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
|
||||
{
|
||||
files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
|
||||
printf("文件夹:%s\n",files[i].c_str());
|
||||
i++;
|
||||
}
|
||||
//}
|
||||
}while(_findnext(hFile, &fileinfo) == 0);
|
||||
_findclose(hFile);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
28
测试/本机测试/2-侯-算法/handwriting/getType.cpp
Normal file
28
测试/本机测试/2-侯-算法/handwriting/getType.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*程序名:getType.c
|
||||
功能:读入图像文件名,得到图像类型
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
char * getType(char fileName[], char type[])
|
||||
{
|
||||
int i=strlen(fileName)-1, j;
|
||||
char ch;
|
||||
|
||||
for(type[0]='\0';i>=0;i--)
|
||||
{
|
||||
if(fileName[i] == '.')
|
||||
{// 遇到文件类型分隔符
|
||||
for(j=i; fileName[j]!='\0'; j++)
|
||||
{
|
||||
ch = fileName[j];
|
||||
type[j-i] = ('A'<=ch && ch<='Z') ? (ch+'a'-'A'): ch;
|
||||
}
|
||||
|
||||
type[j-i] = '\0';
|
||||
break;
|
||||
}
|
||||
else if(fileName[i] == '/' || fileName[i]=='\\') break;// 遇到目录分割符,退出
|
||||
}
|
||||
return type;
|
||||
}
|
||||
58
测试/本机测试/2-侯-算法/handwriting/gif2ipl.cpp
Normal file
58
测试/本机测试/2-侯-算法/handwriting/gif2ipl.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 程序名:gif2ipl.c
|
||||
功能:输入gif图像。得到相应的rgb图像
|
||||
*/
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include "FreeImage.h"
|
||||
#include <stdio.h>
|
||||
IplImage* gif2ipl(const char* filename)
|
||||
{
|
||||
FreeImage_Initialise(); //load the FreeImage function lib
|
||||
FREE_IMAGE_FORMAT fif = FIF_GIF;
|
||||
FIBITMAP* fiBmp = FreeImage_Load(fif,filename,GIF_DEFAULT);
|
||||
FIMULTIBITMAP * pGIF=FreeImage_OpenMultiBitmap(fif,filename,0,1,0,GIF_PLAYBACK);
|
||||
// FIBITMAPINFO fiBmpInfo = getfiBmpInfo(fiBmp);
|
||||
int gifImgCnt=FreeImage_GetPageCount(pGIF);
|
||||
FIBITMAP * pFrame;
|
||||
int width,height;
|
||||
width=FreeImage_GetWidth(fiBmp);
|
||||
height=FreeImage_GetHeight(fiBmp);
|
||||
IplImage * iplImg = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3);
|
||||
iplImg->origin = 1;//should set to 1-top-left structure(Windows bitmap style)
|
||||
RGBQUAD* ptrPalette =new RGBQUAD; // = FreeImage_GetPalette(fiBmp);
|
||||
BYTE intens;
|
||||
BYTE* pIntensity = &intens;
|
||||
//cvNamedWindow("gif",0);
|
||||
//printf("gif包含图片的数目:%d \n",gifImgCnt);
|
||||
for (int curFrame=0;curFrame<gifImgCnt;curFrame++)
|
||||
{
|
||||
pFrame= FreeImage_LockPage(pGIF,curFrame);
|
||||
//ptrPalette = FreeImage_GetPalette(pFrame);
|
||||
char * ptrImgDataPerLine;
|
||||
for (int i=0;i<height;i++)
|
||||
{
|
||||
ptrImgDataPerLine = iplImg->imageData + i*iplImg->widthStep;
|
||||
for(int j=0;j<width;j++)
|
||||
{
|
||||
//get the pixel index
|
||||
//FreeImage_GetPixelIndex(pFrame,j,i,pIntensity);
|
||||
FreeImage_GetPixelColor(pFrame,j,i,ptrPalette);
|
||||
ptrImgDataPerLine[3*j] = ptrPalette->rgbBlue;
|
||||
ptrImgDataPerLine[3*j+1] = ptrPalette->rgbGreen;
|
||||
ptrImgDataPerLine[3*j+2] = ptrPalette->rgbRed;
|
||||
//ptrImgDataPerLine[3*j] = ptrPalette[intens].rgbBlue;
|
||||
//ptrImgDataPerLine[3*j+1] = ptrPalette[intens].rgbGreen;
|
||||
//ptrImgDataPerLine[3*j+2] = ptrPalette[intens].rgbRed;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("转换结束的图片序号: %d \n",curFrame);
|
||||
// cvShowImage("gif",iplImg);
|
||||
// cvWaitKey(30);
|
||||
// FreeImage_UnlockPage(pGIF,pFrame,1);
|
||||
}
|
||||
FreeImage_Unload(fiBmp);
|
||||
FreeImage_DeInitialise();
|
||||
|
||||
return iplImg;
|
||||
}
|
||||
105
测试/本机测试/2-侯-算法/handwriting/handwriting.vcxproj
Normal file
105
测试/本机测试/2-侯-算法/handwriting/handwriting.vcxproj
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4A0EA5CA-C4D6-4A83-9201-B683D6FAEBD5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>handwriting</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<ExecutablePath>C:\Program Files %28x86%29\OpenCV\otherlibs;C:\Program Files %28x86%29\OpenCV\bin;C:\Program Files %28x86%29\OpenCV\cvaux\include;$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>C:\Program Files %28x86%29\OpenCV\cv\include;C:\Program Files %28x86%29\OpenCV\cvaux\include;C:\Program Files %28x86%29\OpenCV\cxcore\include;C:\Program Files %28x86%29\OpenCV\ml\include;C:\Program Files %28x86%29\OpenCV\otherlibs\highgui;C:\Program Files (x86)\OpenCV\;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\OpenCV\cv\src;C:\Program Files %28x86%29\OpenCV\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>cv.lib;cvaux.lib;cxcore.lib;highgui.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Point.h" />
|
||||
<ClInclude Include="Thinner.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="binary.cpp" />
|
||||
<ClCompile Include="Cjbsb.cpp" />
|
||||
<ClCompile Include="getFiles.cpp" />
|
||||
<ClCompile Include="getFolders.cpp" />
|
||||
<ClCompile Include="getType.cpp" />
|
||||
<ClCompile Include="outline.cpp" />
|
||||
<ClCompile Include="outlinefeature.cpp" />
|
||||
<ClCompile Include="read_scanf.cpp" />
|
||||
<ClCompile Include="searchDir.cpp" />
|
||||
<ClCompile Include="segmentation.cpp" />
|
||||
<ClCompile Include="singlefeature.cpp" />
|
||||
<ClCompile Include="Thinner.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
63
测试/本机测试/2-侯-算法/handwriting/handwriting.vcxproj.filters
Normal file
63
测试/本机测试/2-侯-算法/handwriting/handwriting.vcxproj.filters
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Point.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Thinner.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="binary.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Cjbsb.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="getFiles.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="getFolders.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="getType.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="outline.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="outlinefeature.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="read_scanf.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="searchDir.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="segmentation.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="singlefeature.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thinner.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
47
测试/本机测试/2-侯-算法/handwriting/outline.cpp
Normal file
47
测试/本机测试/2-侯-算法/handwriting/outline.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 程序名:outline.c
|
||||
功能:输入文字图像。得到相应的轮廓图
|
||||
*/
|
||||
#pragma once
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
IplImage* outline(IplImage* imgbj)
|
||||
{
|
||||
/*定义变量*/
|
||||
int i,j;
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
|
||||
/*定义新的图像*/
|
||||
IplImage* imglk = cvCreateImage(cvGetSize(imgbj),imgbj->depth,imgbj->nChannels);
|
||||
|
||||
/* 获取图像信息*/
|
||||
height = imgbj->height;
|
||||
width = imgbj->width;
|
||||
step = imgbj->widthStep;
|
||||
channels = imgbj->nChannels;
|
||||
data = (uchar *)imgbj->imageData;
|
||||
|
||||
|
||||
for(j=0;j<height;j++)
|
||||
{
|
||||
for(int i=0;i<width;i++)
|
||||
imglk->imageData[j*step+i*channels]=255;
|
||||
for( i=0;i<width-1;i++)
|
||||
if(data[j*step+(i+1)*channels]-data[j*step+i*channels]==255) //竖线右侧框
|
||||
imglk->imageData[j*step+i*channels]=0;
|
||||
else if(data[j*step+i*channels]-data[j*step+(i+1)*channels]==255) //竖线左侧框
|
||||
imglk->imageData[j*step+(i+1)*channels]=0;
|
||||
}
|
||||
|
||||
for(i=0;i<width;i++)
|
||||
for(j=0;j<height-1;j++)
|
||||
if(data[j*step+i*channels]-data[(j+1)*step+i*channels]==255) //横线下侧框
|
||||
imglk->imageData[(j+1)*step+i*channels]=0;
|
||||
else if(data[(j+1)*step+i*channels]-data[j*step+i*channels]==255) //横线上侧框
|
||||
imglk->imageData[j*step+i*channels]=0;
|
||||
|
||||
return imglk;
|
||||
}
|
||||
264
测试/本机测试/2-侯-算法/handwriting/outlinefeature.cpp
Normal file
264
测试/本机测试/2-侯-算法/handwriting/outlinefeature.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/* 程序名:outline.c
|
||||
功能:输入文字另外由于轮廓图像。返回相应的轮廓特征值
|
||||
*/
|
||||
#pragma once
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "Point.h"
|
||||
|
||||
int outlinefeature(IplImage* imglk,int feature[ ][50]){
|
||||
/*定义变量*/
|
||||
int i,j;
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
|
||||
int feat[50][50]={0}; //特征值初始化
|
||||
Point featblk[32]; //标记相同H的黑点坐标
|
||||
int featk; //标记相同H的黑点数目
|
||||
int m; //for 里面的变量
|
||||
|
||||
/* 获取图像信息*/
|
||||
height = imglk->height;
|
||||
width = imglk->width;
|
||||
step = imglk->widthStep;
|
||||
channels = imglk->nChannels;
|
||||
data = (uchar *)imglk->imageData;
|
||||
|
||||
//初始化特征矩阵 最大值为47 ,非空的特征字有1081个
|
||||
int outllab[9][9]={\
|
||||
{3,37,10,36,2,35,9,34,1},{38,3,21,20,2,19,18,1,33},\
|
||||
{11,22,3,10,2,9,1,17,8},{39,23,11,3,2,1,8,16,32},\
|
||||
{4,4,4,4,0,0,0,0,0},{40,24,12,5,6,7,15,31,47},\
|
||||
{12,25,5,13,6,14,7,30,15},{41,5,26,27,6,28,29,7,46},\
|
||||
{5,42,13,43,6,44,14,45,7}};
|
||||
// for(i=0;i<9;i++) //输出测试
|
||||
// {
|
||||
// for(j=0;j<9;j++)
|
||||
// printf("%d*",outllab[i][j]);
|
||||
// printf("\n");
|
||||
// }
|
||||
for(i=4;i<=width-5;i++)
|
||||
{
|
||||
for(j=4;j<=height-5;j++)
|
||||
{
|
||||
if(data[j*step+i*channels]==0)
|
||||
{
|
||||
//**************H=1
|
||||
|
||||
memset(featblk, 0, sizeof(Point)*32); //归零
|
||||
featk=0;
|
||||
if(data[j*step+(i+1)*channels]==0) //右侧点
|
||||
{
|
||||
featblk[featk].x=i+1;
|
||||
featblk[featk].y=j;
|
||||
featk++;
|
||||
}
|
||||
for(m=i+1;m>=i-1;m--) //上排点
|
||||
{
|
||||
if(data[(j-1)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j-1;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
if(data[j*step+(i-1)*channels]==0) //左侧点
|
||||
{
|
||||
featblk[featk].x=i-1;
|
||||
featblk[featk].y=j;
|
||||
featk++;
|
||||
}
|
||||
for(m=i-1;m<=i+1;m++) //下排点
|
||||
{
|
||||
if(data[(j+1)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j+1;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
//统计特征点
|
||||
//****************************************************
|
||||
if(featk>=2)
|
||||
{
|
||||
for(m=1;m<=featk-1;m++)
|
||||
{
|
||||
feat[outllab[featblk[m-1].x-i+4][featblk[m-1].y-j+4]][outllab[featblk[m].x-i+4][featblk[m].y-j+4]]++;
|
||||
}
|
||||
}
|
||||
//H=1
|
||||
|
||||
|
||||
//H=2
|
||||
memset(featblk, 0, sizeof(Point)*32); //归零
|
||||
featk=0;
|
||||
|
||||
for(m=j+1;m>=j-2;m--)
|
||||
{
|
||||
if(data[m*step+(i+2)*channels]==0) //右排点
|
||||
{
|
||||
featblk[featk].x=i+2;
|
||||
featblk[featk].y=m;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=i+1;m>=i-2;m--) //上排点
|
||||
{
|
||||
if(data[(j-2)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j-2;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=j-1;m<=j+2;m++) //左侧点
|
||||
{
|
||||
if(data[m*step+(i-2)*channels]==0)
|
||||
{
|
||||
featblk[featk].x=i-2;
|
||||
featblk[featk].y=m;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=i-1;m<=i+2;m++) //下排点
|
||||
{
|
||||
if(data[(j+2)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j+2;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
//统计特征点
|
||||
//****************************************************
|
||||
if(featk>=2)
|
||||
{
|
||||
for(m=1;m<=featk-1;m++)
|
||||
{
|
||||
feat[outllab[featblk[m-1].x-i+4][featblk[m-1].y-j+4]][outllab[featblk[m].x-i+4][featblk[m].y-j+4]]++;
|
||||
}
|
||||
}
|
||||
//H=2
|
||||
|
||||
//H=3
|
||||
memset(featblk, 0, sizeof(Point)*32); //归零
|
||||
featk=0;
|
||||
|
||||
for(m=j+2;m>=j-3;m--)
|
||||
{
|
||||
if(data[m*step+(i+3)*channels]==0) //右排点
|
||||
{
|
||||
featblk[featk].x=i+3;
|
||||
featblk[featk].y=m;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=i+2;m>=i-3;m--) //上排点
|
||||
{
|
||||
if(data[(j-3)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j-3;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=j-2;m<=j+3;m++) //左侧点
|
||||
{
|
||||
if(data[m*step+(i-3)*channels]==0)
|
||||
{
|
||||
featblk[featk].x=i-3;
|
||||
featblk[featk].y=m;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=i-2;m<=i+3;m++) //下排点
|
||||
{
|
||||
if(data[(j+3)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j+3;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
//统计特征点
|
||||
//******************************************
|
||||
if(featk>=2)
|
||||
{
|
||||
for(m=1;m<=featk-1;m++)
|
||||
{
|
||||
feat[outllab[featblk[m-1].x-i+4][featblk[m-1].y-j+4]][outllab[featblk[m].x-i+4][featblk[m].y-j+4]]++;
|
||||
}
|
||||
}
|
||||
//H=3
|
||||
|
||||
//H=4
|
||||
memset(featblk, 0, sizeof(Point)*32); //归零
|
||||
featk=0;
|
||||
|
||||
for(m=j+3;m>=j-4;m--)
|
||||
{
|
||||
if(data[m*step+(i+4)*channels]==0) //右排点
|
||||
{
|
||||
featblk[featk].x=i+4;
|
||||
featblk[featk].y=m;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=i+3;m>=i-4;m--) //上排点
|
||||
{
|
||||
if(data[(j-4)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j-4;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=j-3;m<=j+4;m++) //左侧点
|
||||
{
|
||||
if(data[m*step+(i-4)*channels]==0)
|
||||
{
|
||||
featblk[featk].x=i-4;
|
||||
featblk[featk].y=m;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
for(m=i-3;m<=i+4;m++) //下排点
|
||||
{
|
||||
if(data[(j+4)*step+m*channels]==0)
|
||||
{
|
||||
featblk[featk].x=m;
|
||||
featblk[featk].y=j+4;
|
||||
featk++;
|
||||
}
|
||||
}
|
||||
//统计特征点
|
||||
if(featk>=2)
|
||||
{
|
||||
for(m=1;m<=featk-1;m++)
|
||||
{
|
||||
feat[ outllab[featblk[m-1].x-i+4][featblk[m-1].y-j+4]] [outllab[featblk[m].x-i+4][featblk[m].y-j+4] ]++;
|
||||
}
|
||||
}
|
||||
//H=4***********************
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//****注:最终特征值为feat(x,y)+feat(y,x),放入feat(x,y)中,x<y
|
||||
for(i=1;i<50;i++)
|
||||
for(j=0;j<i;j++)
|
||||
{
|
||||
feat[j][i]=feat[i][j]+feat[j][i];
|
||||
feat[i][j]=0;
|
||||
}
|
||||
|
||||
memcpy(feature,feat,2500*4); //int有四个字节
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
27
测试/本机测试/2-侯-算法/handwriting/read_scanf.cpp
Normal file
27
测试/本机测试/2-侯-算法/handwriting/read_scanf.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// 功能:将filename 中的数据(共cols列)读取到_vector中,_vector可视为二维数组
|
||||
#pragma once
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
int read_scanf(const string &filename,const int &cols,vector<double *> &_vector)
|
||||
{
|
||||
FILE *fp=fopen(filename.c_str(),"r");
|
||||
bool flag=true;
|
||||
int i=0;
|
||||
if(!fp) { cout<<"File open error!\n"; return 0; }
|
||||
while(flag)
|
||||
{
|
||||
double *point=new double[cols];
|
||||
for(i=0;i<cols;i++)
|
||||
{ //读取数据,存在_vector[cols]中
|
||||
if(EOF==fscanf(fp,"%lf",&point[i])){flag=false;break;};
|
||||
if(EOF==fgetc(fp)){flag=false;i++;break;}
|
||||
}
|
||||
if(cols==i) _vector.push_back(point);
|
||||
}
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
45
测试/本机测试/2-侯-算法/handwriting/searchDir.cpp
Normal file
45
测试/本机测试/2-侯-算法/handwriting/searchDir.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 程序名:getFiles.c
|
||||
功能:返回一个文件夹下的所有文件名
|
||||
*/
|
||||
#pragma once
|
||||
#include<io.h>
|
||||
#include <stdio.h>
|
||||
#include<vector>
|
||||
#include<iostream>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
int searchDir( char *path, vector<string> &dir)
|
||||
{
|
||||
using namespace std;
|
||||
struct _finddata_t fa;//创建找到的结构体
|
||||
long handle;
|
||||
int flag=0;
|
||||
char temp[100]={0};
|
||||
string path_temp=path;
|
||||
// path_temp=path_temp.substr(0,path_temp.length()-1);
|
||||
|
||||
if((handle = _findfirst(strcat(path,"*"),&fa)) == -1L)//如果不是目录的话
|
||||
return 0;
|
||||
|
||||
do//是目录,先执行循环
|
||||
{
|
||||
if( fa.attrib == _A_SUBDIR && ~strcmp(fa.name,".")&& ~strcmp(fa.name,".."))
|
||||
{
|
||||
strcat( temp, path_temp.c_str());
|
||||
strcat( temp, fa.name);
|
||||
|
||||
if(flag++)
|
||||
dir.push_back(temp);
|
||||
else;
|
||||
|
||||
memset(temp,0,100);
|
||||
}
|
||||
}while(_findnext(handle,&fa) == 0); /* 成功找到时返回0*/
|
||||
|
||||
_findclose(handle);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
246
测试/本机测试/2-侯-算法/handwriting/segmentation.cpp
Normal file
246
测试/本机测试/2-侯-算法/handwriting/segmentation.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/* 程序名:segmentation.c
|
||||
功能:总程序:读入图像文件,分析特征,输出效果
|
||||
*/
|
||||
//#include "stdafx.h"
|
||||
#pragma once
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include "Point.h"
|
||||
#include "Cword.h"
|
||||
//#include "FreeImage.h" //用于读gif的图像,(将gif图像转换为png)
|
||||
#include<io.h> //下面的5个用于读取文件夹下的所有文件名
|
||||
#include<vector>
|
||||
#include<iostream>
|
||||
#include <string.h>
|
||||
#include<windows.h> //用于弹出提示框,,,切记!当调用<windows.h>时,不要调用MFC!(Afx.h)
|
||||
#include<string.h>
|
||||
using namespace std;
|
||||
#ifdef WIN32 //屏蔽VC6对STL的一些不完全支持造成
|
||||
#pragma warning (disable: 4514 4786)
|
||||
#endif
|
||||
|
||||
void getFiles(string path, vector<string>& files );//9、读取文件名下所有文件名
|
||||
void on_mouse( int event, int x, int y, int flags, void* ustc);
|
||||
char* getType(char fileName[], char type[]); //2、获取图像类型
|
||||
int* binary(IplImage* img,int bithro); //3、二值化图像
|
||||
int getFolders(string path, vector<string>& files );//11、读取文件名下所有文件夹的名称
|
||||
int read_scanf(const string &filename,const int &cols,vector<double *> &_vector);//12、读取已经存好的特征值
|
||||
int outlinefeature(IplImage* imglk,int feature[ ][50]); //7、计算图像的轮廓特征值
|
||||
int searchDir(char* path, vector<string> &dir);//获取目录下一层的所有文件夹
|
||||
IplImage* Cjbsb(IplImage* img,IplImage* imgjbsb,int jbwhite,int jbblack);//4、图像角标识别
|
||||
IplImage* worddivide(IplImage* imgbj,int hthro,int wthro,int *gridx,int *gridy,int *gxx,int *gyy); //5、为文字区域画上方格
|
||||
IplImage* outline(IplImage* imgbj); //6、计算图像对应的轮廓图
|
||||
IplImage* gif2ipl(const char* filename); //1、读取gif的外部函数
|
||||
IplImage* wordrecognize(IplImage* imgbj,int *gridx,int *gridy,Cword *wordbox,int gx,int gy);//8、判断方格中的是否为文字
|
||||
IplImage* singlefeature(char* path,int feature[ ][50]);//10、得出单个文件的特征值
|
||||
|
||||
int pos_x=0,pos_y=0;
|
||||
bool pos_flag=false;
|
||||
IplImage* src;
|
||||
int picAll = 0, picSus = 0;
|
||||
int stuAll = 0, stuSus = 0;
|
||||
|
||||
int ComputeImage(vector<string> files, double bzckesa[50][50], double *wcd, int conti)
|
||||
{ int i,ii,jj,k,size;
|
||||
double bzcu[50][50]={0}; //标准差中的u
|
||||
double featurep[50][50][30]={0}; //所有图像的轮廓方向特征初始化//干什么 //30
|
||||
int feature[50][50][30]={0}; //所有图像的特征值初始化 //所有图像指的什么意思 //30找出30的位置或者50的位置限制。。。。带入num_dir==49的情况进行类比
|
||||
int featx[50][50]={0}; //循环赋值的feature
|
||||
int featureall; //图像特征值和 //做什么用
|
||||
IplImage* imglk[30]; //轮廓图变量 //30
|
||||
|
||||
size=files.size();
|
||||
for (i = 0;i < size;i++)
|
||||
{
|
||||
memset(featx,0,sizeof(featx));
|
||||
// strcpy(str,files[i].c_str());
|
||||
imglk[i]=singlefeature((char*)files[i].c_str(),featx); //featx[][50]
|
||||
featureall=0; //图像特征值和的初始化
|
||||
for(ii=0;ii<48;ii++) //将featx存起来,回头看能不能用函数换掉
|
||||
for(jj=ii+1;jj<47;jj++)
|
||||
{
|
||||
feature[ii][jj][i]=featx[ii][jj];
|
||||
featureall=featureall+featx[ii][jj];
|
||||
}
|
||||
//求轮廓方向特征featurep,式(5) 与标准差中的u的和
|
||||
for(ii=0;ii<48;ii++)
|
||||
for(jj=ii+1;jj<47;jj++)
|
||||
{
|
||||
featurep[ii][jj][i]=(double)featx[ii][jj]/featureall;
|
||||
bzcu[ii][jj]+=(double)featx[ii][jj]/featureall*1000; //标准差的值过小,进行放大(1)
|
||||
}
|
||||
}
|
||||
//处理完一个人的每一张图片后
|
||||
for(ii=0;ii<48;ii++)//求标准差中的u
|
||||
for(jj=ii+1;jj<47;jj++)
|
||||
bzcu[ii][jj]=bzcu[ii][jj]/size;
|
||||
//求相似性就是带权卡方wcd
|
||||
for (i = 0;i < size;i++)
|
||||
for(ii=0;ii<48;ii++)
|
||||
for(jj=ii+1;jj<47;jj++)
|
||||
if(featurep[ii][jj][i]*featurep[ii][jj][conti]!=0 && bzckesa[ii][jj]!=-1)
|
||||
wcd[i]+=pow((featurep[ii][jj][i]-featurep[ii][jj][conti]),2)/((featurep[ii][jj][i]+featurep[ii][jj][conti])*bzckesa[ii][jj]);
|
||||
memset(imglk,0,sizeof(imglk));
|
||||
memset(feature,0,sizeof(feature));
|
||||
memset(featurep,0,sizeof(featurep));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
// 定义变量
|
||||
vector<string> dir; //存储目录
|
||||
int conti=1; //对比图像的标号
|
||||
int size_dir,num_dir;
|
||||
char record[2400]={0};
|
||||
|
||||
// 准备结果文件
|
||||
char* fpname= "C:/Users/闫帅帅/Desktop/result2.txt";
|
||||
FILE* fpzz=NULL;//需要注意
|
||||
//fpzz=fopen(fpname,"w+"); //创建文件 //a
|
||||
//if(NULL==fpzz) return -1;//要返回错误代码
|
||||
//fprintf(fpzz,record); //从控制台中读入并在文本输出
|
||||
//fclose(fpzz);
|
||||
//fpzz=NULL;//需要指向空,否则会指向原打开文件地址
|
||||
|
||||
// 获取待检测文件夹到size
|
||||
char path[100] = "E:/xiangmu/Img/imgjiaobiao/";//D:/xiangmu/Img/imgjiaobiao/
|
||||
searchDir(path, dir);//获取filePath下的所有一级目录并存储到dir中
|
||||
|
||||
// dir.push_back("E:/xiangmu/Img/imgjiaobiao/010211100518"); //存储目录
|
||||
size_dir=dir.size(); //dir的大小就是学生的数量
|
||||
stuAll = size_dir;
|
||||
cout << "学生总数为" << stuAll << endl;
|
||||
|
||||
// 开始检测每个文件夹下的
|
||||
for(num_dir=0;num_dir<size_dir;num_dir++)//对每一个学生目录进行循环
|
||||
{
|
||||
int size,i,ii,jj; //通用变量
|
||||
double bzckesa[50][50]={0}; //标准差
|
||||
double wcd[30]={0}; //记录卡方距离 //30应该指的就是每个人的图片数目
|
||||
int featdif[30]={0}; //每幅图的特征值与总特征平均值的差 //30
|
||||
int maxi;float maxx=0; //最大特征值的标号与值
|
||||
int xyimgnum=0; //嫌疑图片的数目
|
||||
|
||||
vector<string> suspict; //记录嫌疑图片地址
|
||||
vector<float> suspict_wcd;
|
||||
vector<string> files; //存储文件路径
|
||||
|
||||
getFiles(dir[num_dir].c_str(), files ); //遍历当前文件夹下的所有文件
|
||||
//输出
|
||||
printf("正在进行第%d,目录为:%s",num_dir,dir[num_dir].c_str());
|
||||
|
||||
size = files.size(); //图像的数目
|
||||
//输出
|
||||
printf("文件个数为:%d\t",size);
|
||||
|
||||
//将标准差中的kesa加载进来
|
||||
string bzcfile="D:/Xiangmu/Img/bzc/bzc.txt";
|
||||
//txt文件中有47列
|
||||
int bzccolumns=47;
|
||||
vector<double *> output_bzc;
|
||||
if(!read_scanf(bzcfile,bzccolumns,output_bzc)) return 0;
|
||||
//output_vector可视为二维数组;输出数组元素:
|
||||
//int rows=output_bzc.size();
|
||||
for(ii=0;ii<48;ii++)
|
||||
for(jj=ii+1;jj<47;jj++)
|
||||
bzckesa[ii][jj]=output_bzc[ii][jj];
|
||||
|
||||
//开始对每一张图片进行处理
|
||||
for(int r=0;r<size;r++)
|
||||
{
|
||||
memset(wcd, 0, sizeof(wcd));
|
||||
ComputeImage(files, bzckesa, wcd, r);
|
||||
xyimgnum=0;
|
||||
//求卡方距离的最大值
|
||||
for (i = 0;i < size;i++)
|
||||
{
|
||||
// cout << files[i].c_str()<< " " << wcd[i] << endl;
|
||||
// if(maxx<wcd[i]){ maxx=wcd[i]; maxi=i;}
|
||||
if(wcd[i]>0.12)
|
||||
{
|
||||
xyimgnum++;
|
||||
suspict.push_back(files[i].c_str());
|
||||
suspict_wcd.push_back(wcd[i]);
|
||||
}
|
||||
}
|
||||
if (xyimgnum<3) break;
|
||||
}
|
||||
|
||||
//将结果存入txt
|
||||
//------------------------------------------------------//
|
||||
char record[8000];
|
||||
memset(record, 0, sizeof(record));
|
||||
char pic_num[20];
|
||||
memset(pic_num, 0, sizeof(pic_num));
|
||||
_itoa(size, pic_num, 10);
|
||||
strcat(record, dir[num_dir].substr(27, 22).c_str()); //学号
|
||||
strcat(record, "\t");
|
||||
strcat(record,pic_num);
|
||||
if(xyimgnum>0)
|
||||
{
|
||||
stuSus++;
|
||||
char b[20];
|
||||
sprintf(b, "\t%d", xyimgnum);
|
||||
strcat(record, b);
|
||||
strcat(record, "\n");
|
||||
// cout << xyimgnum << endl;;
|
||||
for(int t=0;t<xyimgnum;t++)
|
||||
{
|
||||
strcat(record,"\t\t\t");
|
||||
strcat(record,suspict[t].c_str());
|
||||
strcat(record,"\t");
|
||||
char a[80];
|
||||
memset(a,0, sizeof(a));
|
||||
//cout << " " << suspict_wcd[t]<<endl;
|
||||
//cout<< "adwada"<<endl;
|
||||
sprintf(a, "%f", suspict_wcd[t]);
|
||||
strcat(record,a);
|
||||
strcat(record,"\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(record, "\t0\n");
|
||||
}
|
||||
|
||||
fpzz=fopen(fpname,"a"); //创建文件 //a
|
||||
if(NULL==fpzz) return -1;//要返回错误代码
|
||||
fprintf(fpzz,record); //从控制台中读入并在文本输出
|
||||
fclose(fpzz);
|
||||
fpzz=NULL;//需要指向空,否则会指向原打开文件地址
|
||||
|
||||
suspict.clear();
|
||||
suspict_wcd.clear();
|
||||
output_bzc.clear();
|
||||
|
||||
memset(record,0,2400);
|
||||
memset(bzckesa,0,sizeof(bzckesa));
|
||||
memset(wcd,0,sizeof(wcd));
|
||||
memset(featdif,0,sizeof(featdif));
|
||||
|
||||
printf("嫌疑数量:%d\t",xyimgnum);
|
||||
|
||||
picAll += size;
|
||||
picSus += xyimgnum;
|
||||
printf("全部:%d嫌疑:%d比例为:%g\n",picAll, picSus,((float)picSus)/((float)picAll));
|
||||
xyimgnum=0;
|
||||
|
||||
}
|
||||
|
||||
dir.clear();
|
||||
|
||||
cout << "学生总数:" << stuAll << " 作弊人数:" << stuSus << endl;
|
||||
printf("已经打印到txt中!");
|
||||
system("start C:/Users/闫帅帅/Desktop/result2.txt");
|
||||
system("pause");
|
||||
|
||||
return 0; //(1-wcd[maxi])*100
|
||||
|
||||
}
|
||||
171
测试/本机测试/2-侯-算法/handwriting/singlefeature.cpp
Normal file
171
测试/本机测试/2-侯-算法/handwriting/singlefeature.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/* 程序名:singlefeature.c
|
||||
功能:分总程序:读入图像文件,得出单个文件的特征值
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include "Point.h"
|
||||
#include "Cword.h"
|
||||
//#include "FreeImage.h" //用于读gif的图像
|
||||
#include<io.h> //下面的5个用于读取文件夹下的所有文件名
|
||||
#include<vector>
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include <string.h>
|
||||
#include <direct.h>
|
||||
#include"Thinner.h"
|
||||
|
||||
/*各种声明*/
|
||||
|
||||
void getFiles(string path, vector<string>& files );//读取文件名下所有文件
|
||||
char* getType(char fileName[], char type[]); //获取图像类型
|
||||
int* binary(IplImage* img,int bithro); //二值化图像
|
||||
int outlinefeature(IplImage* imglk,int feature[ ][50]);//计算图像的轮廓特征值
|
||||
IplImage* Cjbsb(IplImage* img,IplImage* imgjbsb,int jbwhite,int jbblack);//图像角标识别
|
||||
IplImage* gif2ipl(const char* filename); //读取gif的外部函数
|
||||
|
||||
IplImage* singlefeature(char* path,int feature[ ][50]){
|
||||
//定义变量
|
||||
IplImage* img = 0; //原图
|
||||
IplImage* imglk = 0; //轮廓图
|
||||
IplImage* imggj = 0; //骨架图
|
||||
IplImage* imgjbsb = 0; //角标识别图
|
||||
IplImage* imgbj = 0; //只提取笔记部分的图像
|
||||
IplImage* imgbjhf = 0; //为文字区域画上方格
|
||||
IplImage* imgwzbj = 0; //为文字区域标出是否为文字(文字标记)
|
||||
|
||||
char imgtype[10]; //判断图像类型
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
|
||||
int i,j;
|
||||
int *black; //用于返回图像每行黑像素的个数
|
||||
//int feature[50][50]={0}; //特征值初始化
|
||||
|
||||
img=cvLoadImage(path,0);
|
||||
|
||||
/* 获取图像信息*/
|
||||
height = img->height;
|
||||
width = img->width;
|
||||
step = img->widthStep;
|
||||
channels = img->nChannels;
|
||||
data = (uchar *)img->imageData;
|
||||
|
||||
/*开始处理*/
|
||||
|
||||
/*图像放大*/
|
||||
IplImage* imgbig = 0; //原图的放大图
|
||||
CvSize dst_cvsize; //目标图像的大小
|
||||
float scale=1;
|
||||
if(width<840){
|
||||
scale=(float)840/width;
|
||||
dst_cvsize.width=880;
|
||||
dst_cvsize.height=(int)(height*scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_cvsize.width=width;
|
||||
dst_cvsize.height=height;
|
||||
}
|
||||
|
||||
imgbig=cvCreateImage(dst_cvsize,img->depth,img->nChannels);
|
||||
cvResize(img,imgbig,CV_INTER_LINEAR); // CV_INTER_NN - 最近邻插值,
|
||||
//CV_INTER_LINEAR - 双线性插值 (缺省使用),
|
||||
//CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。
|
||||
//CV_INTER_CUBIC - 立方插值.
|
||||
|
||||
/*二值化*/
|
||||
int bithro=230; //输入二值化的阈值 (0--255)
|
||||
black=binary(imgbig,bithro); //二值化,并统计黑像素的个数,返回每行黑像素的个数(black)
|
||||
//cvNamedWindow("二值化结果图",CV_WINDOW_AUTOSIZE); //显示图像
|
||||
//cvShowImage("二值化结果图",img);
|
||||
//printf("二值化求解完成!!\n");
|
||||
|
||||
|
||||
|
||||
/*角标识别*/
|
||||
int jbwhite=5,jbblack=4;
|
||||
imgjbsb = cvCreateImage(cvGetSize(imgbig),imgbig->depth,imgbig->nChannels);
|
||||
imgbj=Cjbsb(imgbig,imgjbsb,jbwhite,jbblack); //返回文字的笔迹部分
|
||||
|
||||
|
||||
/*计算骨架图*/
|
||||
imggj = cvCreateImage(cvGetSize(imgbj),imgbj->depth,imgbj->nChannels); //复制
|
||||
cvCopy(imgbj,imggj,NULL);
|
||||
uchar *gjdata= (uchar *)imggj->imageData;
|
||||
|
||||
beforethin(gjdata,gjdata,imggj->width, imggj->height);
|
||||
|
||||
for(j=0;j<imggj->height;j++)
|
||||
{ //取值范围转到0--1
|
||||
|
||||
for(i=0;i<imggj->width;i++)
|
||||
{
|
||||
if(gjdata[j*imggj->widthStep+i]==255)
|
||||
gjdata[j*imggj->widthStep+i]=1;
|
||||
}
|
||||
}
|
||||
ThinnerRosenfeld(imggj->imageData, imggj->height, imggj->width);
|
||||
|
||||
for(j=0;j<imggj->height;j++)
|
||||
{//取值范围转到0--255,反转过来
|
||||
for(i=0;i<imggj->width;i++)
|
||||
{
|
||||
if(gjdata[j*imggj->widthStep+i]==1)
|
||||
gjdata[j*imggj->widthStep+i]=0;
|
||||
else
|
||||
gjdata[j*imggj->widthStep+i]=255;
|
||||
}
|
||||
}
|
||||
|
||||
//保存图像 应先生成图像文件名
|
||||
/*
|
||||
char processPic[100]="E:/imggj/";
|
||||
char *namePic=new char[20];
|
||||
bool flag=false;
|
||||
string xuehao=path,kaoshihao=path;
|
||||
int num_iter=sizeof(path);
|
||||
for(int iter=0;iter<num_iter;iter++)
|
||||
{
|
||||
if(path[iter]=='x')
|
||||
{
|
||||
flag=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(flag)
|
||||
{
|
||||
xuehao=xuehao.substr(27,13);
|
||||
kaoshihao=kaoshihao.substr(40,5);
|
||||
}else
|
||||
{
|
||||
xuehao=xuehao.substr(27,12);
|
||||
kaoshihao=kaoshihao.substr(39,5);
|
||||
}
|
||||
strcat(processPic,xuehao.c_str());
|
||||
_mkdir(processPic);
|
||||
strcat(processPic,kaoshihao.c_str());
|
||||
strcat(processPic,".jpg");
|
||||
cvSaveImage(processPic,imggj);
|
||||
*/
|
||||
/*计算骨架特征徝*/
|
||||
outlinefeature(imggj,feature); //特征值占48*48的右上三角形,feature调用返回
|
||||
//cvWaitKey(0);
|
||||
|
||||
/*释放内存*/
|
||||
cvReleaseImage(&imgbig);
|
||||
cvReleaseImage(&img );
|
||||
cvReleaseImage(&imgbj );
|
||||
cvReleaseImage(&imglk );
|
||||
cvReleaseImage(&imgjbsb );
|
||||
cvReleaseImage(&imgbjhf );
|
||||
cvReleaseImage(&imgwzbj );
|
||||
cvDestroyAllWindows();
|
||||
|
||||
return imggj;
|
||||
}
|
||||
|
||||
|
||||
136
测试/本机测试/2-侯-算法/handwriting/worddivide.cpp
Normal file
136
测试/本机测试/2-侯-算法/handwriting/worddivide.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/* 程序名:Cjbsb.c
|
||||
功能:读入只有文字区域的图像文件,将文字划分开来
|
||||
输入参数:只有文字区域的图像文件,行阈值,列阈值,划格后的行标与列标
|
||||
默认:hthro=10,wthro=6
|
||||
*/
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
IplImage* worddivide(IplImage* imgbj,int hthro,int wthro,int *gridx,int *gridy,int *gxx,int *gyy){
|
||||
/*定义变量*/
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
|
||||
int i,j,black[1000];
|
||||
int blackend=0; //标记分割线结束
|
||||
int mi=0,mx=500; //标记分割线内含黑色最少的线号与值
|
||||
int gx=0,gy=0; //记录该画线的网线的行号与列号 gridx[10],gridy[30],
|
||||
memset(gridx,0,10); //初始化内存,这里用做清零
|
||||
memset(gridy,0,30); //初始化内存,这里用做清零
|
||||
|
||||
/*定义新的图像*/
|
||||
IplImage* imgbjhf = cvCreateImage(cvGetSize(imgbj),imgbj->depth,imgbj->nChannels); //笔迹划分图
|
||||
cvCopy(imgbj,imgbjhf,NULL);
|
||||
|
||||
/* 获取图像信息*/
|
||||
height = imgbjhf->height;
|
||||
width = imgbjhf->width;
|
||||
step = imgbjhf->widthStep;
|
||||
channels = imgbjhf->nChannels;
|
||||
data = (uchar *)imgbjhf->imageData;
|
||||
|
||||
|
||||
/*横向的表格*/
|
||||
/*计算每一行的黑色像素点数(此参数不能使用二值化得到的)*/
|
||||
int tempBlackPixelx=0; //循环记录每一行的黑色像素点数
|
||||
|
||||
memset(black,0,1000); //初始化内存,这里用做清零
|
||||
for(j=0;j<height;j++){
|
||||
for(i=0;i<width;i++){
|
||||
if(data[j*step+i*channels]==0) //计算黑色的像素数
|
||||
tempBlackPixelx+=1;
|
||||
}
|
||||
black[j]=tempBlackPixelx; //black记录黑色像素数
|
||||
tempBlackPixelx=0;
|
||||
//printf("The %dth black num is %d \n",j,black[j]);
|
||||
}
|
||||
|
||||
/*计算横线位置*/
|
||||
for(i=0;i<height;i++){
|
||||
if(black[i]<=hthro && blackend==0){
|
||||
blackend=1;
|
||||
if(black[i]<=mx){ //更新黑色最少的的线标
|
||||
mx=black[i];
|
||||
mi=i;
|
||||
}
|
||||
}
|
||||
else if((blackend==1 && black[i]>hthro) || i==height-1){
|
||||
blackend=0;
|
||||
|
||||
gridx[gx]=mi;
|
||||
//printf("<行标:%d>",gridx[gx]);
|
||||
gx++;
|
||||
mx=500;
|
||||
mi=i;
|
||||
}
|
||||
}
|
||||
|
||||
/*纵向的表格*/
|
||||
|
||||
//计算每一列的黑像素个数
|
||||
int tempBlackPixely=0;
|
||||
memset(black,0,1000); //初始化内存,这里用做清零
|
||||
for(i=0;i<width;i++) {
|
||||
for(j=0;j<height;j++){
|
||||
if(data[j*step+i*channels]==0) //计算黑色的像素数
|
||||
tempBlackPixely+=1;
|
||||
}
|
||||
black[i]=tempBlackPixely; //black记录黑色像素数
|
||||
tempBlackPixely=0;
|
||||
}
|
||||
|
||||
/*计算纵线位置*/
|
||||
for(i=0;i<width;i++){
|
||||
if(black[i]<=wthro){
|
||||
if(blackend==0){
|
||||
blackend=1;
|
||||
}
|
||||
if(black[i]<=mx){ //更新黑色最少的的线标
|
||||
mx=black[i];
|
||||
mi=i;
|
||||
}
|
||||
}
|
||||
else if((blackend==1 && black[i]>wthro)){
|
||||
blackend=0;
|
||||
|
||||
if(gy==0){
|
||||
gridy[gy]=mi; //记下黑色最少的的线位置
|
||||
gy++;
|
||||
}
|
||||
else if(mi-gridy[gy-1]<=25){ //考虑方格太小的情况,将其分入上一个方格中
|
||||
gridy[gy-1]=mi; //
|
||||
}
|
||||
else{
|
||||
gridy[gy]=mi; //记下黑色最少的的线位置
|
||||
//printf("<列标:%d>",gridy[gy]);
|
||||
gy++;
|
||||
}
|
||||
mx=500;
|
||||
mi=i;
|
||||
}
|
||||
}
|
||||
|
||||
gridy[gy]=mi; //对最后一列进行处理
|
||||
gy++;
|
||||
//for(j=0;j<gy;j++)
|
||||
// printf("The %dth row is %d \n",j,gridy[j]);
|
||||
//for(i=0;i<gx;i++)
|
||||
// printf("The %dth line is %d \n",i,gridx[i]);
|
||||
|
||||
/*笔迹划分图上画上方格*/
|
||||
for(i=0;i<height;i++)
|
||||
for(j=0;j<gy;j++)
|
||||
data[i*step+gridy[j]*channels]=0;
|
||||
|
||||
for(i=0;i<width;i++)
|
||||
for(j=0;j<gx;j++)
|
||||
data[gridx[j]*step+i*channels]=0;
|
||||
|
||||
*gxx=gx;
|
||||
*gyy=gy;
|
||||
//printf("分割完成\n");
|
||||
|
||||
return imgbjhf;
|
||||
}
|
||||
81
测试/本机测试/2-侯-算法/handwriting/wordrecognize.cpp
Normal file
81
测试/本机测试/2-侯-算法/handwriting/wordrecognize.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 程序名:wordrecorgnize.c
|
||||
功能:输入文字图像及方格位置。识别含有有效字符的方格
|
||||
*/
|
||||
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "Point.h"
|
||||
#include "Cword.h"
|
||||
|
||||
IplImage* wordrecognize(IplImage* imgbj,int *gridx,int *gridy,Cword *wordbox,int gx,int gy){
|
||||
/*定义变量*/
|
||||
int i,j,ni,numw,nblack=0,wnum=0;
|
||||
//Cword wordbox[150];
|
||||
int sumnum=(gx-1)*(gy-1);
|
||||
|
||||
int height,width,step,channels;
|
||||
uchar *data;
|
||||
|
||||
/*定义新的图像*/
|
||||
IplImage* imgwzbj = cvCreateImage(cvGetSize(imgbj),imgbj->depth,imgbj->nChannels);
|
||||
cvCopy(imgbj,imgwzbj,NULL);
|
||||
uchar *wzbjdata = (uchar *)imgwzbj->imageData;
|
||||
|
||||
/* 获取图像信息*/
|
||||
height = imgbj->height;
|
||||
width = imgbj->width;
|
||||
step = imgbj->widthStep;
|
||||
channels = imgbj->nChannels;
|
||||
data = (uchar *)imgbj->imageData;
|
||||
|
||||
/*开始处理*/
|
||||
for(i=0;i<gx-1;i++)
|
||||
for(j=0;j<gy-1;j++){
|
||||
numw=i*(gy-1)+j+1;
|
||||
wordbox[numw].wbegin.x=gridx[i];
|
||||
wordbox[numw].wbegin.y=gridy[j];
|
||||
wordbox[numw].wend.x=gridx[i+1];
|
||||
wordbox[numw].wend.y=gridy[j+1];
|
||||
//printf("The %dth word*** \n",numw);
|
||||
}
|
||||
//printf("The %dth word \n",numw);
|
||||
//printf("The sum of words: %d \n",sumnum);
|
||||
|
||||
for(ni=1;ni<=sumnum;ni++){
|
||||
for(i=wordbox[ni].wbegin.x;i<wordbox[ni].wend.x;i++)
|
||||
for(j=wordbox[ni].wbegin.y;j<wordbox[ni].wend.y;j++){
|
||||
if(data[i*step+j*channels]==0) //计算黑色的像素数
|
||||
nblack+=1;
|
||||
}
|
||||
if(nblack>80){
|
||||
wordbox[ni].isword=true;
|
||||
wnum++;
|
||||
wordbox[ni].nn=wnum;
|
||||
|
||||
//printf("x= %d;;;y=%d \n",wordbox[ni].wbegin.x,wordbox[ni].wbegin.y);
|
||||
wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+2)*channels]=0; //标在一幅图上,是文字,标一个+
|
||||
wzbjdata[(wordbox[ni].wbegin.x+1)*step+(wordbox[ni].wbegin.y+2)*channels]=0;
|
||||
wzbjdata[(wordbox[ni].wbegin.x+3)*step+(wordbox[ni].wbegin.y+2)*channels]=0;
|
||||
wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+1)*channels]=0;
|
||||
wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+3)*channels]=0;
|
||||
//wzbjdata[(wordbox[ni].wbegin.x)*step+(wordbox[ni].wbegin.y+2)*channels]=0;
|
||||
//wzbjdata[(wordbox[ni].wbegin.x+4)*step+(wordbox[ni].wbegin.y+2)*channels]=0;
|
||||
//wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y)*channels]=0;
|
||||
//wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+4)*channels]=0;
|
||||
}
|
||||
else{
|
||||
wordbox[ni].isword=false;
|
||||
|
||||
wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+2)*channels]=0; //标在一幅图上,不是文字,标一个-
|
||||
wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+1)*channels]=0;
|
||||
wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+3)*channels]=0;
|
||||
//wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y)*channels]=0;
|
||||
//wzbjdata[(wordbox[ni].wbegin.x+2)*step+(wordbox[ni].wbegin.y+4)*channels]=0;
|
||||
}
|
||||
wordbox[ni].blacknum=nblack;
|
||||
nblack=0;
|
||||
}
|
||||
return imgwzbj;
|
||||
}
|
||||
Reference in New Issue
Block a user