笔迹鉴别程序

考试的笔迹鉴别程序,分辨出不同人写的笔迹
This commit is contained in:
yanshui177
2017-05-17 16:50:37 +08:00
parent abe00d2e02
commit 962de04ffb
205 changed files with 17672 additions and 0 deletions

View 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}") = "HWCV-exe", "HWCV-exe\HWCV-exe.vcxproj", "{FB6A1EE7-710E-424B-A80E-A931EDB7DDBF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FB6A1EE7-710E-424B-A80E-A931EDB7DDBF}.Debug|Win32.ActiveCfg = Debug|Win32
{FB6A1EE7-710E-424B-A80E-A931EDB7DDBF}.Debug|Win32.Build.0 = Debug|Win32
{FB6A1EE7-710E-424B-A80E-A931EDB7DDBF}.Release|Win32.ActiveCfg = Release|Win32
{FB6A1EE7-710E-424B-A80E-A931EDB7DDBF}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,209 @@
/*
实现文件DBop.cpp 数据库操作实现文件
*/
#include "DBop.h"
#include "path.h"
/*本地的全局变量*/
_ConnectionPtr p_conn; /*全局变量 连接对象*/
_RecordsetPtr p_recordset; /*全局变量 记录集对象*/
_CommandPtr p_cmd; /*全局变量 操作集对象*/
string str_conn; /*全局变量 连接字符串设置*/
/**
程序功能: 根据string类的stu【存储学号】搜索出所有此人的考试信息,并分别存储在不同的变量中
@变量 stuNum 学号
@变量 date<vector> 考试时间
@变量 subject<vector> 考试科目
@变量 stuNum<vector> 考号
@返回值 成功1 失败0
*/
int DbImg(string stuNum, vector<string>& dateVec, vector<string>& subjectVec, vector<string>& stuNum2)//搜寻图片
{
/*字符转换,方便使用*/
string userName(g_db_userName.c_str());
string password(g_db_password.c_str());
string hostName(g_db_hostName.c_str());
string dBName(g_db_dBName.c_str());
//cout<<g_db_userName.c_str()<<endl;
//cout<<g_db_password.c_str()<<endl;
//cout<<g_db_hostName.c_str()<<endl;
//cout<<g_db_dBName.c_str()<<endl;
/*创建链接描述符*/
//Provider=OraOLEDB.Oracle.1;Persist Security Info = true;User ID = BJSH;Password=bjshadmin;Data Source = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST=192.168.200.97)(PORT=1521))
//(CONNECT_DATA=(SERVICE_NAME=purple)))",
str_conn = "Provider=OraOLEDB.Oracle.1;Persist Security Info = true;User ID = ";
str_conn += userName; //===仅初始化一次===//
str_conn += ";Password="; //==================//
str_conn += password;
str_conn += ";Data Source = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST=";
str_conn += hostName;
str_conn += ")(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=";
str_conn += dBName;
str_conn += ")))";
//构造查询语句 下句注释是sql语句需要构造成这种类型
/*select KS_ZKZ, KSSJ, TJ_KC_DM from ZK.T_BYSQ_KS_KC WHERE KSSJ between '200907' and '201510' and KS_ZKZ = 010207203867*/
/*string sql = "select KS_ZKZ2, KSSJ, TJ_KC_DM from ZK.T_BYSQ_KS_KC WHERE KSSJ between '200907' and '201504' AND KS_ZKZ = ";*/
// select KS_ZKZ, KSSJ, TJ_KC_DM from ZK.T_BYSQ_KS_KC WHERE KSSJ between '200907' and '201510' and KS_ZKZ = 010214100225
//"select KS_ZKZ, KSSJ, TJ_KC_DM from ZK.T_BYSQ_KS_KC WHERE KSSJ between '200907' and '201510' and KS_ZKZ = 010214100225",
string sql = "select KS_ZKZ, KSSJ, TJ_KC_DM from ";
sql += g_db_hoster_zk;
sql += ".T_BYSQ_KS_KC WHERE KSSJ between ";
sql += g_db_qurry_start;
sql += " and ";
sql += g_db_qurry_end;
sql += "AND KS_ZKZ =";
sql += stuNum.c_str();
_bstr_t _vstr_sql(sql.c_str());/* 转换string为_variant_t */
::CoInitialize(NULL);//初始化com组件
/*创建、打开连接*/
try{
p_conn.CreateInstance("ADODB.Connection");//创建连接
p_recordset.CreateInstance("ADODB.Recordset");//创建结果集,也就是实例化
p_conn->CursorLocation = adUseClient; //存储过程同时返回记录集和返回值
p_conn->Open(_bstr_t(str_conn.c_str()),
//p_conn->Open("Provider=OraOLEDB.Oracle.1;Persist Security Info = true;User ID = BJSH;Password=bjshadmin;Data Source = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST=192.168.200.97)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=purple)))",
_bstr_t(userName.c_str()),
_bstr_t(password.c_str()),
adConnectUnspecified);
// SaveLog((char*)str_conn.c_str(), g_log_adr, "a");
HRESULT hr = p_recordset->Open(_bstr_t(_vstr_sql),//执行sq语句查询一个学生的所有考试信息
//HRESULT hr = p_recordset->Open("select KS_ZKZ, KSSJ, TJ_KC_DM from ZK.T_BYSQ_KS_KC WHERE KSSJ between '200907' and '201510' and KS_ZKZ = 010214100225",
p_conn.GetInterfacePtr(),
adOpenStatic,
adLockOptimistic,
adCmdText);
cout<<"count:"<<p_recordset->RecordCount <<endl;
//将结果集输出到三个vector变量中
if (p_recordset->RecordCount < 1)//结果集为空
{
return 0;//没有信息,直接跳过这个人
}
do{ //将结果集输出到三个vector变量中
dateVec.push_back((string)(_bstr_t)(p_recordset->Fields->GetItem(_variant_t("KSSJ"))->GetValue()));
subjectVec.push_back((string)(_bstr_t)(p_recordset->Fields->GetItem(_variant_t("TJ_KC_DM"))->GetValue()));
stuNum2.push_back((string)(_bstr_t)(p_recordset->Fields->GetItem(_variant_t("KS_ZKZ"))->GetValue()));
p_recordset->MoveNext();
} while (!p_recordset->EndOfFile);
}
catch (_com_error e)
{
/*printf("%x", e.Error());
cout<<"Failed"<<endl;*/
memset(g_log_rec, 0, sizeof(g_log_rec));
strcat(g_log_rec, "DBImg-Err:");
strcat(g_log_rec, (char*)e.Description());
strcat(g_log_rec, " ");
strcat(g_log_rec, (char*)e.Error());
strcat(g_log_rec, " ");
SaveLog(g_log_rec, g_log_adr, "a");
::CoUninitialize();
return 0;
}
/*关闭查询*/
return 1;
}
/**
程序功能: 更新学生数据库信息,根据学生的鉴定结果,将结果输出到数据库中
@变量 stuNum学号
@变量 subject考试科目
@变量 flagCheat作弊标记
@返回值 成功1失败0
*/
int DbUpdate(string stuNum, vector<string> dateVec, vector<string> subjectVec, vector<string> stuNum2, vector<string> flagVec)
{
/*字符转换,方便使用*/
string userName(g_db_userName.c_str());
string password(g_db_password.c_str());
string hostName(g_db_hostName.c_str());
string dBName(g_db_dBName.c_str());
/*更新字串设置*/
int count = subjectVec.size();
vector<string> sqlKC; //课程表:作弊第一字段
int ci = 0; //循环
/*构造更新语句*/
for (ci = 0; ci < count; ++ci)
{
/*作弊的*/
string sqlKC1 = "UPDATE ";
sqlKC1 += g_db_hoster_zk;
sqlKC1 += ".T_BYSQ_KS_KC SET BJSH_JG_JQ =";//天津_课程_代码
sqlKC1 += flagVec[ci].c_str();
sqlKC1 += " WHERE KS_ZKZ2=";
sqlKC1 += stuNum2[ci].c_str();
sqlKC1 += " AND TJ_KC_DM=";
sqlKC1 += subjectVec[ci].c_str();
sqlKC1 += " AND KSSJ=";
sqlKC1 += dateVec[ci].c_str();
sqlKC1 += " AND KS_ZKZ=";
sqlKC1 += stuNum.c_str();
sqlKC.push_back(sqlKC1);
}
::CoInitialize(NULL);//初始化com组件
/*更新数据库表*/
try{
p_conn.CreateInstance("ADODB.Connection");//创建连接
p_recordset.CreateInstance("ADODB.Recordset");//创建结果集,也就是实例化
p_cmd.CreateInstance("ADODB.Command");
p_conn->CursorLocation = adUseClient; //存储过程同时返回记录集和返回值
p_conn->Open(_bstr_t(str_conn.c_str()), _bstr_t(userName.c_str()), _bstr_t(password.c_str()), adConnectUnspecified);
p_cmd->ActiveConnection = p_conn;
for (ci = 0; ci < count; ++ci)
{
p_recordset->Open(_bstr_t(sqlKC[ci].c_str()),//更新第二条
p_conn.GetInterfacePtr(),
adOpenStatic,
adLockOptimistic,
adCmdText);
}
}
catch (_com_error e)
{
memset(g_log_rec, 0, sizeof(g_log_rec));
strcat(g_log_rec, "DBUpdate-Err:");
strcat(g_log_rec, (char*)e.Description());
strcat(g_log_rec, " ");
strcat(g_log_rec, (char*)e.Error());
strcat(g_log_rec, " ");
SaveLog(g_log_rec, g_log_adr, "a");
::CoUninitialize();
return 0;
}
/*关闭查询*/
::CoUninitialize();
return 1;
}

View File

@@ -0,0 +1,55 @@
/*
头文件DBop.h 数据库操作头文件
*/
#pragma once
#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF","EndOfFile")
#include <vector>
#include <string>
#include <iostream>
#include <windows.h>
#include <iomanip>
#include <stdio.h>
using namespace std;
/*全局变量*/
extern char g_log_adr[50]; /*全局变量 程序日志存储地址*/
extern char g_log_rec[500]; /*全局变量 程序日志专用变量*/
extern FILE *g_log_fpzz; /*全局变量 程序日志专用文件句柄*/
extern string g_db_hostName; /*全局变量 服务器ip或名称*/
extern string g_db_dBName; /*全局变量 服务器ODBC数据源*/
extern string g_db_userName; /*全局变量 服务器用户名*/
extern string g_db_password; /*全局变量 服务器密码*/
extern string g_db_qurry_start; /*全局变量 数据库查询_开始日期*/
extern string g_db_qurry_end; /*全局变量 数据库查询_结束日期*/
extern string g_db_qurry_zone; /*全局变量 数据库查询_特定区域*/
extern string g_db_qurry_stu_num; /*全局变量 数据库查询_特定考号*/
extern bool g_db_qurry_all; /*全局变量 数据库查询_查询全部标记*/
extern string g_db_hoster_zk; /*全局变量 数据库用户zk考试院的zk本地的yannsy*/
/*****************************************函数原型*************************************/
/**
程序功能: 根据string类的stu【存储学号】搜索出所有此人的考试信息,并分别存储在不同的变量中
@变量 stuNum 学号
@变量 date<vector> 考试时间
@变量 subject<vector> 考试科目
@变量 stuNum<vector> 考号
@返回值 成功1 失败0
*/
int DbImg(string stuNum, vector<string>& dateVec, vector<string>& subjectVec, vector<string>& stuNum2);
/**
程序功能: 更新学生数据库信息,根据学生的鉴定结果,将结果输出到数据库中
@变量 stuNum学号
@变量 subject考试科目
@变量 flagCheat作弊标记
@返回值 成功1失败0
*/
int DbUpdate(string stuNum, vector<string> dateVec, vector<string> subjectVec, vector<string> stuNum2, vector<string> flagVec);

View File

@@ -0,0 +1,106 @@
<?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>{FB6A1EE7-710E-424B-A80E-A931EDB7DDBF}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>HWCVexe</RootNamespace>
<ProjectName>HWCV</ProjectName>
</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>
<UseOfMfc>Static</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Static</UseOfMfc>
</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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<LibraryPath>C:\Program Files %28x86%29\OpenCV\lib;$(VC_LibraryPath_x86);$(WindowsSdk_71A_LibraryPath_x86)</LibraryPath>
<ExecutablePath>C:\Program Files %28x86%29\OpenCV\otherlibs;C:\Program Files %28x86%29\OpenCV\bin;C:\Program Files %28x86%29\OpenCV\cvaux\include;$(VC_ExecutablePath_x86);$(WindowsSdk_71A_ExecutablePath);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH)</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>
</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>libjasperd.lib;libjpegd.lib;libpngd.lib;libtiffd.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;comctl32.lib;%(AdditionalDependencies)</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;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<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>
<ItemGroup>
<ClInclude Include="path.h" />
<ClInclude Include="Point.h" />
<ClInclude Include="process.h" />
<ClInclude Include="segmentation.h" />
<ClInclude Include="StdAfx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="path.cpp" />
<ClCompile Include="process.cpp" />
<ClCompile Include="segmentation.cpp" />
<ClCompile Include="seg_bck.cpp" />
<ClCompile Include="StdAfx.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,51 @@
<?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="path.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Point.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="process.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="segmentation.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="StdAfx.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="path.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="process.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="segmentation.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="StdAfx.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="seg_bck.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
/*
头文件Point.h 图像中的像素点定义
*/
#pragma once
class Point{
private:
public:
int x;
int y;
void setpoint(int a,int b){x=a;y=b;}
};

View File

@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// HWCV.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@@ -0,0 +1,24 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__0B833134_257D_4F21_9707_24C780138809__INCLUDED_)
#define AFX_STDAFX_H__0B833134_257D_4F21_9707_24C780138809__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__0B833134_257D_4F21_9707_24C780138809__INCLUDED_)

View File

@@ -0,0 +1,264 @@
/*
实现文件path.cpp 路径操作实现文件
*/
#include "path.h"
/**
获取并返回当前时间
*/
char* GetTime()
{
time( &ltime );
srcTime = ctime( &ltime );
strncpy(timeNow, srcTime, strlen(srcTime)-1); //不拷贝换行
timeNow[strlen(srcTime)-1] = '\0'; //加结束符'\0'
return timeNow;
}
/**
根据学生信息创建文件路径,用于文件读取
@变量 date 考试日期
@变量 subject 考试科目
@变量 stuNum 考号
@返回值 返回生成的文件路径
*/
string CrPath(string date, string subject, string stuNum)
{
string temp = g_dir; temp += date; temp += "/";
temp += subject.substr(0, 4); temp += "/";
temp += stuNum; temp += ".jpg";
return temp;
}
/*
功能:读取标准差文件
@变量 filesname 文件名
@变量 col 行数
@变量 _vector 读取到的标准差存到vector中
@返回值 成功1失败0
*/
int ReadScanf(const string &filename, const int &cols, vector<double *> &_vector)
{
// 功能将filename 中的数据共cols列读取到_vector中_vector可视为二维数组
FILE *fp = fopen(filename.c_str(), "r");//打开并读取文件
bool flag = true;
int i = 0;
// printf("--read_scanf--");
if (!fp){ 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;
}
/**
读取配置文件,并配置各项参数
@变量 filename 配置文件的路径
@返回值 成功1 失败0
*/
int ReadConfig(char *filename)
{
ifstream file(filename);
if (!file)/*"配置文件不存在!"*/
{
/*写入时间*/
memset(g_log_rec, 0, sizeof(g_log_rec));
cout<<"read"<<endl;
strcat(g_log_rec, "--ERR:配置文件不存在!");
SaveLog(g_log_rec, g_err_adr, "a");
return 0;
}
/*步骤:开始读取信息*/
string temp;/*仅用作过滤字符*/
file >> temp >> temp;
/*---此行6个参考配置信息图片对比参数*/
file >> temp >> temp >> temp >> temp >> temp >>temp;
file >> g_dir >> temp >> temp >> temp;
string g_log_adr_t;
file >> g_log_adr_t >> temp;
memset(g_log_adr, 0, sizeof(g_log_adr));
strcpy(g_log_adr, (char*)g_log_adr_t.c_str());
/*---此行6个参考配置信息网络配置参数*/
file >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp;
/*---此行5个参考配置信息控制参数*/
file >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp;
/*---此行5个参考配置信息数据库查询参数*/
file >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp;
file.close();/*关闭文件句柄*/
return 1;
}
/**
函数功能存储过程数据到txt文件
@变量: record 存储的语句
@变量 g_txt_file_path 存储的位置
@返回值 1成功 0失败
*/
int SaveLog(char *txt, string txt_file_path, char *type)
{
FILE* fpzz = fopen(txt_file_path.c_str(), type); //创建文件
if (NULL == fpzz)
{
return 0;
}//要返回错误代码
fprintf(fpzz, txt); //从控制台中读入并在文本输出
fclose(fpzz);
fpzz = NULL;//需要指向空,否则会指向原打开文件地址
return 1;
}
/*
功能:保存中间鉴定图像(不实现,没有必要)
@变量
@变量
@返回值
*/
int SaveImg(IplImage *img, char *g_process_img_adr){
return 1;
}
/*
功能:获取指定目录下的文件
@变量 path 路径
@变量 files 输出vector格式的文件
*/
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));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
/*
功能:获取指定目录下的目录
@变量 path 目录
@变量 files 返回的目录vector
@返回值 成功1失败0
*/
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;
}
/*
功能:搜索目录
*/
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;
}

View File

@@ -0,0 +1,122 @@
/*
头文件path.h 与路径相关操作的函数头文件以及函数原型
*/
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <ctime>
#include <cv.h>
#include <io.h>
using namespace std;
extern int g_bi_threshold; /*全局变量 二值化阈值*/
extern double g_std_kesa[50][50]; /*全局变量 标准差数组*/
extern float g_doubt_threshold; /*全局变量 作弊嫌疑阈值*/
extern string g_dir; /*全局变量 总路径的目录*/
extern int g_conti; /*全局变量 比较标准*/
extern string g_db_hostName; /*全局变量 服务器ip或名称*/
extern string g_db_dBName; /*全局变量 服务器ODBC数据源*/
extern string g_db_userName; /*全局变量 服务器用户名*/
extern string g_db_password; /*全局变量 服务器密码*/
extern char g_log_adr[50]; /*全局变量 程序日志存储地址*/
extern char g_err_adr[50]; /*全局变量 错误日志存储地址*/
extern char g_log_rec[500]; /*全局变量 程序日志专用变量*/
/*全局变量 待定*/
/*全局变量 待定*/
extern string g_db_qurry_start; /*全局变量 数据库查询_开始日期*/
extern string g_db_qurry_end; /*全局变量 数据库查询_结束日期*/
extern string g_db_qurry_zone; /*全局变量 数据库查询_特定区域*/
extern string g_db_qurry_stu_num; /*全局变量 数据库查询_特定考号*/
extern bool g_db_qurry_all; /*全局变量 数据库查询_查询全部标记*/
extern string g_db_hoster_zk;
extern time_t ltime;
extern char *srcTime;
extern char timeNow[32];
extern char msg[100];
/**
获取并返回当前时间
*/
char* GetTime();
/**
根据学生信息创建文件路径,用于文件读取
@变量 date 考试日期
@变量 subject 考试科目
@变量 stuNum 考号
@返回值 返回生成的文件路径
*/
string CrPath(string date, string subject, string stuNum);
/*
功能:读取标准差文件
@变量 filesname 文件名
@变量 col 行数
@变量 _vector 读取到的标准差存到vector中
@返回值 成功1失败0
*/
int ReadScanf(const string &filename, const int &cols, vector<double *> &_vector);
/**
读取配置文件,并配置各项参数
@变量 filename 配置文件的路径
@返回值 成功1 失败0
*/
int ReadConfig(char *filename);
/**
函数功能存储过程数据到txt文件
@变量: record 存储的语句
@变量 g_txt_file_path 存储的位置
@返回值 1成功 0失败
*/
int SaveLog(char *record, string txt_file_path, char *type);
/*
功能:保存中间鉴定图像
@变量
@变量
@返回值
*/
int SaveImg(IplImage *img, char *g_process_img_adr);
/*
功能:获取指定目录下的文件
@变量 path 路径
@变量 files 输出vector格式的文件
*/
void getFiles(string path, vector<string>& files);
/*
功能:获取指定目录下的目录
@变量 path 目录
@变量 files 返回的目录vector
@返回值 成功1失败0
*/
int getFolders(string path, vector<string>& files);
/*
功能:搜索目录
*/
int searchDir(char *path, vector<string> &dir);

View File

@@ -0,0 +1,665 @@
/*
实现文件process.cpp 图像处理过程的实现文件
*/
#include "process.h"
/*
功能:读入图像文件,进行二值化
@变量 img iplimage图像文件
@变量 bithro 二值化阈值
@返回值 黑像素的数目(待用)
*/
int* binary(IplImage* img, int g_bi_threshold)
{
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]>g_bi_threshold) ? 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;
}
/*
功能:读入图像文件,对图像进行裁剪
@变量 img iplimage图像文件
@变量 img 裁剪后的iplimage图像文件
@jbwhite
@jbblack
@返回值 返回裁剪后的图像
*/
IplImage* Cjbsb(IplImage* img, IplImage* imgjbsb, int jbwhite, int jbblack)
{
/*定义变量*/
int i, j, 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;
}
/*
功能:计算图像的特征
@变量 imgbj 笔迹部分的图像
@返回值 计算得到的特征图像
*/
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;
// printf("--outline--");
for (j = 0; j<height; j++){
for (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;
}
/*
功能:输入图像的特征轮廓图,返回图像的特征值
@变量 imglk 输入的图像轮廓图
@变量 feature 得到的图像特征
@返回值 成功1失败0
*/
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 里面的变量
// printf("--outlinefeature--");
// 获取图像信息
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 = 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***********************
}// if
} //for j
} //for i
//****注最终特征值为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有四个字节
// printf("轮廓特征值计算完成\n");
return 0;
}
/*
功能:对单张图像的处理,最终得到一个特征值,用来计算各个图像之间的卡方距离
@变量 path 图像的物理地址
@变量 feature 图像的特征值
@返回值 处理后的图像
*/
IplImage* singlefeature(char* path, int feature[][50])
{
//定义变量
//原图
IplImage* imglk = 0; //轮廓图
IplImage* imggj = 0; //骨架图
IplImage* imgjbsb = 0; //角标识别图
IplImage* imgbj = 0; //只提取笔记部分的图像
IplImage* imgbjhf = 0; //为文字区域画上方格
IplImage* imgwzbj = 0; //为文字区域标出是否为文字(文字标记)
int height, width, step, channels;
uchar *data;
int i, j; //用于返回图像每行黑像素的个数
//int feature[50][50]={0}; //特征值初始化
IplImage* 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 = 840;
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 - 立方插值.
/*二值化*/
binary(imgbig, g_bi_threshold);
//SaveLog("singlefeature_binary\n", "D:\\HWCV\\numtxt.txt", "a");
/*裁剪识别*/
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;
}
}
/*计算骨架特征徝*/
outlinefeature(imggj, feature); //特征值占48*48的右上三角形feature调用返回
/*释放内存*/
cvReleaseImage(&imgbig);
cvReleaseImage(&img);
cvReleaseImage(&imgbj);
cvReleaseImage(&imglk);
cvReleaseImage(&imgjbsb);
cvReleaseImage(&imgbjhf);
cvReleaseImage(&imgwzbj);
cvDestroyAllWindows();
return imggj;
}
/*
功能细化之前的图像颜色处理将颜色范围转换到0-1
@变量 ip 图像的句柄
@变量 jp
@变量 lx 图象宽度
@变量 ly 图象高度
@返回值 空
*/
void beforethin(unsigned char *ip, unsigned 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;
}
}
}
/*功能:细化算法 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;
// printf("--Thinner_Rosenfeld--");
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);
}

View File

@@ -0,0 +1,97 @@
/*
头文件process.h 图像处理函数头文件
*/
#pragma once
#include "Point.h"
#include "path.h"
#include "process.h"
#include <cv.h>
#include <direct.h>
#include <io.h>
#include <iostream>
#include <math.h>
#include <malloc.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
/*全局变量*/
extern IplImage* src;
/***************************************函数原型****************************************/
/*
功能:读入图像文件,进行二值化
@变量 img iplimage图像文件
@变量 bithro 二值化阈值
@返回值 黑像素的数目(待用)
*/
int* binary(IplImage* img, int bithro);
/*
功能:读入图像文件,对图像进行裁剪
@变量 img iplimage图像文件
@变量 img 裁剪后的iplimage图像文件
@jbwhite
@jbblack
@返回值 返回裁剪后的图像
*/
IplImage* Cjbsb(IplImage* img, IplImage* imgjbsb, int jbwhite, int jbblack);
/*
功能:计算图像的特征
@变量 imgbj 笔迹部分的图像
@返回值 计算得到的特征图像
*/
IplImage* outline(IplImage* imgbj);
/*
功能:输入图像的特征轮廓图,返回图像的特征值
@变量 imglk 输入的图像轮廓图
@变量 feature 得到的图像特征
@返回值 成功1失败0
*/
int outlinefeature(IplImage* imglk, int feature[][50]);
/*
功能:对单张图像的处理,最终得到一个特征值,用来计算各个图像之间的卡方距离
@变量 path 图像的物理地址
@变量 feature 图像的特征值
@返回值 处理后的图像
*/
IplImage* singlefeature(char* path, int feature[][50]);
/*
功能细化之前的图像颜色处理将颜色范围转换到0-1
@变量 ip 图像的句柄
@变量 jp
@变量 lx 图象宽度
@变量 ly 图象高度
@返回值 空
*/
void beforethin(unsigned char *ip, unsigned char *jp, unsigned long lx, unsigned long ly);
/*功能:细化算法 Rosenfeld细化算法用于完成对笔迹图像的股价提取
@变量 image 代表图象的一维数组
@变量 lx 图象宽度
@变量 ly 图象高度
@返回值 无返回值
*/
void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly);

View File

@@ -0,0 +1,219 @@
///*
//主函数文件segmentation.cpp 主函数的实现文件
//*/
//#include "segmentation.h"
////#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )//无界面运行
///*主函数*/
//int ComputeImage(vector<string> files, double bzckesa[50][50], double *wcd, int conti);
//int main(int argc, char* argv[])
//{
// /*变量定义*/
// string dir = "E:\\xiangmu\\Img\\imgjiaobiao\\010211100518"; //存储目录
// //string dir;
// //if (argc < 2)
// // return -1;
// //else
// // dir = argv[1];
// cout << (char*)dir.c_str() << endl;
// char record[2400] = { 0 };
// FILE* fpzz = NULL;//需要注意
// int i, ii, jj, feature[50][50][30] = { 0 }, featureall = 0;
// double featurep[50][50][30] = { 0 };
// double bzcu[50][50] = { 0 };
// double bzckesa[50][50] = { 0 };
// double wcd[30] = { 0 };
//
// int featx[50][50] = { 0 };
// int featdif[30] = { 0 };
// float maxx = 0; //最大特征值的标号与值
// int xyimgnum = 0; //嫌疑图片的数目
// char str[80]; //存储地址
//
// vector<string> suspict; //记录嫌疑图片地址
// vector<float> suspict_wcd; //嫌疑图片的wcd值
// vector<string> files; //存储该生所有考试文件路径
//
// /*读取配置文件,并配置各项参数*/
// if (!ReadConfig("D:/HWCV/config/configure.cfg"))
// {
// // SaveLog("\t配置文件读取失败\n", g_log_adr, "a");
// SaveLog("\n0\n", g_log_adr, "a");
// return 0;
// }
// char path[100] = "E:/xiangmu/Img/imgjiaobiao/";
//
//
//
// /*步骤:读取标准差文件*/
// int bzccolumns = 47;//txt文件中有47列
// vector<double *> output_bzc;
// if (!ReadScanf("D:\\HWCV\\config\\stdfile.db", bzccolumns, output_bzc))
// {
// memset(g_log_rec, 0, sizeof(g_log_rec));
//
// // SaveLog("\n读取路径D:\\HWCV\\config\\stdfile.db 的标准差文件失败!\n", g_log_adr, "a");
// SaveLog("\n0\n", g_log_adr, "a");
// return 0;
// }
//
// //开始检测
// //-------------------------------------------------------------//
// getFiles(dir.c_str(), files); //遍历当前文件夹下的所有文件
// int size = files.size();
//
// for (i = 0; i < size; i++)
// {
// // cout << ".";
// memset(str, 0, sizeof(str));
// memset(featx, 0, sizeof(featx));
// memset(bzcu, 0, sizeof(bzcu));
//
// strcpy(str, files[i].c_str());
// singlefeature(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
// }
// }/*处理完全部图片*/
//
// /*求标准差中u*/
// for (ii = 0; ii < 48; ii++)
// for (jj = ii + 1; jj < 47; jj++)
// bzcu[ii][jj] = bzcu[ii][jj] / size;
//
//
// for (ii = 0; ii < 48; ii++)//output_vector可视为二维数组;输出数组元素:
// for (jj = ii + 1; jj < 47; jj++)
// bzckesa[ii][jj] = output_bzc[ii][jj];
//
// /*求相似性即带权卡方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][g_conti] != 0 && bzckesa[ii][jj] != -1)
// wcd[i] += pow((featurep[ii][jj][i] - featurep[ii][jj][g_conti]), 2) / ((featurep[ii][jj][i] + featurep[ii][jj][g_conti])*bzckesa[ii][jj]);
//
// //标出所有有嫌疑的图像1无嫌疑的图像0
// for (i = 0; i < size; i++)
// {
// if (wcd[i] > 0.12)
// {
// xyimgnum++;
// suspict.push_back(files[i].c_str());
// suspict_wcd.push_back(wcd[i]);
// }
// }
//
// /*将结果存入log文件*/
// strcat(g_log_rec, "\n");
// memset(g_log_rec, 0, sizeof(g_log_rec));
// // strcat(g_log_rec, GetTime());
// // strcat(g_log_rec, "\t考生考号");
// strcat(g_log_rec, dir.substr(27, 22).c_str());
// strcat(g_log_rec, "\t");//图片总数为:
// char pic_num[20];
// _itoa(size, pic_num, 10);
// strcat(g_log_rec, pic_num);
// if (xyimgnum > 0)
// {
// char b[20];
// sprintf(b, "\t%d", xyimgnum);
// strcat(g_log_rec, b);
// strcat(g_log_rec, "\n");
// for (i = 0; i < xyimgnum; i++)
// {
// // cout << "嫌疑图像:" << files[i].c_str() << endl;
// strcat(g_log_rec, "\t\t\t");//\t嫌疑图像
// strcat(g_log_rec, suspict[i].c_str());
// strcat(g_log_rec, "\t");//相似度:
// float sim = (1.0 - suspict_wcd[i]) * 100;
// char a[20];
// sprintf(a, "%g", sim);
// strcat(g_log_rec, a);
// strcat(g_log_rec, "%%\n");
// }
// }
// else
// {
// // strcat(g_log_rec, "\t该考生没有嫌疑图像\n");
// strcat(g_log_rec, "\t0\n");
// // cout << "该考生无嫌疑图像!" << endl;
// }
// SaveLog(g_log_rec, g_log_adr, "a");
//
//
// /*善后*/
// suspict.clear();
// suspict_wcd.clear();
// memset(g_log_rec, 0, sizeof(g_log_rec));
// memset(feature, 0, sizeof(feature));
// memset(featurep, 0, sizeof(featurep));
// memset(bzckesa, 0, sizeof(bzckesa));
// memset(wcd, 0, sizeof(wcd));
// memset(featdif, 0, sizeof(featdif));
// files.clear();
// memset(g_log_rec, 0, sizeof(g_log_rec));
//
// /*返回值*/
// return 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;
//}

View File

@@ -0,0 +1,225 @@
/*
主函数文件segmentation.cpp 主函数的实现文件
*/
#include "segmentation.h"
//#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )//无界面运行
/*主函数*/
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; //图像特征值和 //做什么用
size = files.size();
for (i = 0; i < size; i++)
{
memset(featx, 0, sizeof(featx));
// strcpy(str,files[i].c_str());
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(feature, 0, sizeof(feature));
memset(featurep, 0, sizeof(featurep));
return 1;
}
int main(int argc, char* argv[])
{
/*变量定义*/
//string dir;
//if (argc < 2)
// return -1;
//else
// dir = argv[1];
// 调试
// string dir = "E:/xiangmu/Img/imgjiaobiao/010211100518"; //存储目录
// 定义变量
vector<string> dir; //存储目录
int conti = 1; //对比图像的标号
int size_dir, num_dir;
char record[2400] = { 0 };
// 获取待检测文件夹到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++)//对每一个学生目录进行循环
{
cout <<(char*)dir[num_dir].c_str();
char record[2400] = { 0 };
FILE* fpzz = NULL;//需要注意
int i, ii, jj, feature[50][50][30] = { 0 }, featureall = 0;
double featurep[50][50][30] = { 0 };
double bzcu[50][50] = { 0 };
double bzckesa[50][50] = { 0 };
double wcd[30] = { 0 };
int featx[50][50] = { 0 };
int featdif[30] = { 0 };
float maxx = 0; //最大特征值的标号与值
int xyimgnum = 0; //嫌疑图片的数目
char str[80]; //存储地址
vector<string> suspict; //记录嫌疑图片地址
vector<float> suspict_wcd; //嫌疑图片的wcd值
vector<string> files; //存储该生所有考试文件路径
/*读取配置文件,并配置各项参数*/
if (!ReadConfig("D:/HWCV/config/configure.cfg"))
{
// SaveLog("\t配置文件读取失败\n", g_log_adr, "a");
SaveLog("\n0\n", g_log_adr, "a");
return 0;
}
char path[100] = "E:/xiangmu/Img/imgjiaobiao/";
/*步骤:读取标准差文件*/
int bzccolumns = 47;//txt文件中有47列
vector<double *> output_bzc;
if (!ReadScanf("D:\\HWCV\\config\\stdfile.db", bzccolumns, output_bzc))
{
memset(g_log_rec, 0, sizeof(g_log_rec));
// SaveLog("\n读取路径D:\\HWCV\\config\\stdfile.db 的标准差文件失败!\n", g_log_adr, "a");
SaveLog("\n0\n", g_log_adr, "a");
return 0;
}
for (ii = 0; ii < 48; ii++)//output_vector可视为二维数组;输出数组元素:
for (jj = ii + 1; jj < 47; jj++)
bzckesa[ii][jj] = output_bzc[ii][jj];
//开始检测
//-------------------------------------------------------------//
getFiles(dir[num_dir].c_str(), files); //遍历当前文件夹下的所有文件
int size = files.size();
cout << " 文件数:" << size;
//开始对每一张图片进行处理
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 (wcd[i]>0.12)
{
xyimgnum++;
suspict.push_back(files[i].c_str());
suspict_wcd.push_back(wcd[i]);
}
}
if (xyimgnum < 3) break;
}
/*将结果存入log文件*/
memset(g_log_rec, 0, sizeof(g_log_rec));
// strcat(g_log_rec, GetTime());
// strcat(g_log_rec, "\t考生考号");
strcat(g_log_rec, dir[num_dir].substr(27, 22).c_str());//学号
strcat(g_log_rec, ",");//图片总数为:
char pic_num[20];
_itoa(size, pic_num, 10);
strcat(g_log_rec, pic_num);
if (xyimgnum > 0)
{
stuSus++;
char b[20];
sprintf(b, ",%d", xyimgnum);
strcat(g_log_rec, b);
strcat(g_log_rec, "\n");
for (i = 0; i < xyimgnum; i++)
{
// cout << "嫌疑图像:" << files[i].c_str() << endl;
strcat(g_log_rec, ",,,");//\t嫌疑图像
strcat(g_log_rec, suspict[i].c_str());
strcat(g_log_rec, ",");//相似度:
float sim = (1.0 - suspict_wcd[i]) * 100;
char a[20];
sprintf(a, "%g", sim);
strcat(g_log_rec, a);
strcat(g_log_rec, "%%\n");
}
}
else
{
// strcat(g_log_rec, "\t该考生没有嫌疑图像\n");
strcat(g_log_rec, ",0,");
// cout << "该考生无嫌疑图像!" << endl;
}
SaveLog(g_log_rec, g_log_adr, "a");
printf("嫌疑数量:%d, ", xyimgnum);
picAll += size;
picSus += xyimgnum;
printf("全部:%d嫌疑%d比例为%g\n", picAll, picSus, ((float)picSus) / ((float)picAll));
xyimgnum = 0;
/*善后*/
suspict.clear();
suspict_wcd.clear();
memset(g_log_rec, 0, sizeof(g_log_rec));
memset(feature, 0, sizeof(feature));
memset(featurep, 0, sizeof(featurep));
memset(bzckesa, 0, sizeof(bzckesa));
memset(wcd, 0, sizeof(wcd));
memset(featdif, 0, sizeof(featdif));
files.clear();
memset(g_log_rec, 0, sizeof(g_log_rec));
/*返回值*/
}
dir.clear();
cout << "学生总数:" << stuAll << " 作弊人数:" << stuSus << endl;
printf("已经打印到txt中");
string open = "start " + (string)g_log_adr;
system(open.c_str());
system("pause");
return 0; //(1-wcd[maxi])*100
}

View File

@@ -0,0 +1,45 @@
/*
头文件segmentation.h 主函数头文件
*/
#pragma once
#ifdef WIN32 //屏蔽VC6对STL的一些不完全支持造成
#pragma warning (disable: 4514 4786)
#endif
#include "StdAfx.h"
#include "path.h"
#include "Point.h"
#include "process.h"
using namespace std;
/*定义全局变量*/
int g_bi_threshold = 230; /* 全局变量 二值化阈值*/
double g_std_kesa[50][50]; /* 全局变量 标准差数组*/
float g_doubt_threshold = 0.12; /* 全局变量 作弊嫌疑阈值*/
string g_dir = "Y:/"; /* 全局变量 总路径的目录*/
int g_cheat_num_threshold = 0; /* 全局变量 默认作弊阈值*/
int g_conti = 1; /* 全局变量 默认作弊比较的图片*/
int g_all_img_num = 0; /* 全局变量 已鉴定的全部图片数量*/
int g_doubt_img_num = 0; /* 全局变量 已鉴定怀疑的图片数量*/
int g_all_stu_num = 0; /* 全局变量 已鉴定的全部学生数量*/
int g_doubt_stu_num = 0; /* 全局变量 已鉴定怀疑的学生数量*/
bool g_output_cmd_config = false; /*全局变量 输出参数控制*/
bool g_output_txt_config = false; /*全局变量 输出中间文件选项*/
char g_log_adr[50] = "D:/HWCV/log_ori.txt"; /*全局变量 程序日志存储地址*/
char g_log_rec[500] = { 0 }; /*全局变量 程序日志专用变量*/
char g_err_adr[50]= "D:/HWCV/err_ori.txt"; /*错误日志路径*/
/*全局变量 输出txt结果文件*/
/*全局变量 输出txt结果文件地址*/
int picAll =0, picSus=0;
int stuAll = 0, stuSus = 0;
time_t ltime;
char *srcTime=NULL;
char timeNow[32]={0};
char msg[100]={0};

View 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

View 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;
}

View File

@@ -0,0 +1,11 @@
class Cword{
private:
public:
Point wbegin;
Point wend;
// int n; //在总个数中的位置
int nn; //在文字中的序号
bool isword; //是否为文字
int blacknum; //本文字中的黑色像素数
};

View 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;
} */

View File

@@ -0,0 +1,9 @@
class Point{
private:
public:
int x;
int y;
void setpoint(int a,int b){x=a;y=b;}
};

View 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;
}
*/

View 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);

View 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;
}

View 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;
}

View 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);
}
}

View 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;
}

View 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;
}

View 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;
}

View 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>

View 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>

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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>时不要调用MFCAfx.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
}

View 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;
}

View File

@@ -0,0 +1,136 @@
/* 程序名Cjbsb.c
功能:读入只有文字区域的图像文件,将文字划分开来
输入参数:只有文字区域的图像文件,行阈值,列阈值,划格后的行标与列标
默认hthro=10wthro=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;
}

View 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;
}

View File

@@ -0,0 +1,133 @@
# Microsoft Developer Studio Project File - Name="HWCV_vc6" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=HWCV_vc6 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "HWCV_vc6.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "HWCV_vc6.mak" CFG="HWCV_vc6 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "HWCV_vc6 - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "HWCV_vc6 - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "HWCV_vc6 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x804 /d "NDEBUG"
# ADD RSC /l 0x804 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "HWCV_vc6 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x804 /d "_DEBUG"
# ADD RSC /l 0x804 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "HWCV_vc6 - Win32 Release"
# Name "HWCV_vc6 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\path.cpp
# End Source File
# Begin Source File
SOURCE=.\process.cpp
# End Source File
# Begin Source File
SOURCE=.\segmentation.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\path.h
# End Source File
# Begin Source File
SOURCE=.\Point.h
# End Source File
# Begin Source File
SOURCE=.\process.h
# End Source File
# Begin Source File
SOURCE=.\segmentation.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# 警告: 不能编辑或删除该工作区文件!
###############################################################################
Project: "HWCV_vc6"=".\HWCV_vc6.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

Binary file not shown.

View File

@@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: HWCV_vc6 - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
HWCV_vc6.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@@ -0,0 +1,14 @@
/*
头文件Point.h 图像中的像素点定义
*/
#pragma once
#include "StdAfx.h"
class Point{
private:
public:
int x;
int y;
void setpoint(int a,int b){x=a;y=b;}
};

View File

@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// HWCV.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@@ -0,0 +1,24 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__0B833134_257D_4F21_9707_24C780138809__INCLUDED_)
#define AFX_STDAFX_H__0B833134_257D_4F21_9707_24C780138809__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__0B833134_257D_4F21_9707_24C780138809__INCLUDED_)

View File

@@ -0,0 +1,263 @@
/*
实现文件path.cpp 路径操作实现文件
*/
#include "path.h"
/**
获取并返回当前时间
*/
char* GetTime()
{
time( &ltime );
srcTime = ctime( &ltime );
strncpy(timeNow, srcTime, strlen(srcTime)-1); //不拷贝换行
timeNow[strlen(srcTime)-1] = '\0'; //加结束符'\0'
return timeNow;
}
/**
根据学生信息创建文件路径,用于文件读取
@变量 date 考试日期
@变量 subject 考试科目
@变量 stuNum 考号
@返回值 返回生成的文件路径
*/
string CrPath(string date, string subject, string stuNum)
{
string temp = g_dir; temp += date; temp += "/";
temp += subject.substr(0, 4); temp += "/";
temp += stuNum; temp += ".jpg";
return temp;
}
/*
功能:读取标准差文件
@变量 filesname 文件名
@变量 col 行数
@变量 _vector 读取到的标准差存到vector中
@返回值 成功1失败0
*/
int ReadScanf(const string &filename, const int &cols, vector<double *> &_vector)
{
// 功能将filename 中的数据共cols列读取到_vector中_vector可视为二维数组
FILE *fp = fopen(filename.c_str(), "r");//打开并读取文件
bool flag = true;
int i = 0;
// printf("--read_scanf--");
if (!fp){ 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;
}
/**
读取配置文件,并配置各项参数
@变量 filename 配置文件的路径
@返回值 成功1 失败0
*/
int ReadConfig(char *filename)
{
ifstream file(filename);
if (!file)/*"配置文件不存在!"*/
{
/*写入时间*/
memset(g_log_rec, 0, sizeof(g_log_rec));
cout<<"read"<<endl;
strcat(g_log_rec, "--ERR:配置文件不存在!");
SaveLog(g_log_rec, g_err_adr, "a");
return 0;
}
/*步骤:开始读取信息*/
string temp;/*仅用作过滤字符*/
file >> temp >> temp;
/*---此行6个参考配置信息图片对比参数*/
file >> temp >> temp >> temp >> temp >> temp >>temp;
file >> g_dir >> temp >> temp >> temp;
string g_log_adr_t;
file >> g_log_adr_t >> temp;
memset(g_log_adr, 0, sizeof(g_log_adr));
strcpy(g_log_adr, (char*)g_log_adr_t.c_str());
/*---此行6个参考配置信息网络配置参数*/
file >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp;
/*---此行5个参考配置信息控制参数*/
file >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp;
/*---此行5个参考配置信息数据库查询参数*/
file >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp >> temp;
file.close();/*关闭文件句柄*/
return 1;
}
/**
函数功能存储过程数据到txt文件
@变量: record 存储的语句
@变量 g_txt_file_path 存储的位置
@返回值 1成功 0失败
*/
int SaveLog(char *txt, string txt_file_path, char *type)
{
FILE* fpzz = fopen(txt_file_path.c_str(), type); //创建文件
if (NULL == fpzz)
{
return 0;
}//要返回错误代码
fprintf(fpzz, txt); //从控制台中读入并在文本输出
fclose(fpzz);
fpzz = NULL;//需要指向空,否则会指向原打开文件地址
return 1;
}
/*
功能:保存中间鉴定图像(不实现,没有必要)
@变量
@变量
@返回值
*/
int SaveImg(IplImage *img, char *g_process_img_adr){
return 1;
}
/*
功能:获取指定目录下的文件
@变量 path 路径
@变量 files 输出vector格式的文件
*/
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));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
/*
功能:获取指定目录下的目录
@变量 path 目录
@变量 files 返回的目录vector
@返回值 成功1失败0
*/
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;
}
/*
功能:搜索目录
*/
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;
}

View File

@@ -0,0 +1,123 @@
/*
头文件path.h 与路径相关操作的函数头文件以及函数原型
*/
#pragma once
#include "StdAfx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <ctime>
#include <cv.h>
#include <io.h>
using namespace std;
extern int g_bi_threshold; /*全局变量 二值化阈值*/
extern double g_std_kesa[50][50]; /*全局变量 标准差数组*/
extern float g_doubt_threshold; /*全局变量 作弊嫌疑阈值*/
extern string g_dir; /*全局变量 总路径的目录*/
extern int g_conti; /*全局变量 比较标准*/
extern string g_db_hostName; /*全局变量 服务器ip或名称*/
extern string g_db_dBName; /*全局变量 服务器ODBC数据源*/
extern string g_db_userName; /*全局变量 服务器用户名*/
extern string g_db_password; /*全局变量 服务器密码*/
extern char g_log_adr[50]; /*全局变量 程序日志存储地址*/
extern char g_err_adr[50]; /*全局变量 错误日志存储地址*/
extern char g_log_rec[500]; /*全局变量 程序日志专用变量*/
/*全局变量 待定*/
/*全局变量 待定*/
extern string g_db_qurry_start; /*全局变量 数据库查询_开始日期*/
extern string g_db_qurry_end; /*全局变量 数据库查询_结束日期*/
extern string g_db_qurry_zone; /*全局变量 数据库查询_特定区域*/
extern string g_db_qurry_stu_num; /*全局变量 数据库查询_特定考号*/
extern bool g_db_qurry_all; /*全局变量 数据库查询_查询全部标记*/
extern string g_db_hoster_zk;
extern time_t ltime;
extern char *srcTime;
extern char timeNow[32];
extern char msg[100];
/**
获取并返回当前时间
*/
char* GetTime();
/**
根据学生信息创建文件路径,用于文件读取
@变量 date 考试日期
@变量 subject 考试科目
@变量 stuNum 考号
@返回值 返回生成的文件路径
*/
string CrPath(string date, string subject, string stuNum);
/*
功能:读取标准差文件
@变量 filesname 文件名
@变量 col 行数
@变量 _vector 读取到的标准差存到vector中
@返回值 成功1失败0
*/
int ReadScanf(const string &filename, const int &cols, vector<double *> &_vector);
/**
读取配置文件,并配置各项参数
@变量 filename 配置文件的路径
@返回值 成功1 失败0
*/
int ReadConfig(char *filename);
/**
函数功能存储过程数据到txt文件
@变量: record 存储的语句
@变量 g_txt_file_path 存储的位置
@返回值 1成功 0失败
*/
int SaveLog(char *record, string txt_file_path, char *type);
/*
功能:保存中间鉴定图像
@变量
@变量
@返回值
*/
int SaveImg(IplImage *img, char *g_process_img_adr);
/*
功能:获取指定目录下的文件
@变量 path 路径
@变量 files 输出vector格式的文件
*/
void getFiles(string path, vector<string>& files);
/*
功能:获取指定目录下的目录
@变量 path 目录
@变量 files 返回的目录vector
@返回值 成功1失败0
*/
int getFolders(string path, vector<string>& files);
/*
功能:搜索目录
*/
int searchDir(char *path, vector<string> &dir);

View File

@@ -0,0 +1,713 @@
/*
实现文件process.cpp 图像处理过程的实现文件
*/
#include "process.h"
int ComputeImage(vector<string> files, double bzckesa[50][50], double *wcd, int conti)
{
cout<<"1231s"<<endl;
int i, ii, jj, 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;
}
/*
功能:读入图像文件,进行二值化
@变量 img iplimage图像文件
@变量 bithro 二值化阈值
@返回值 黑像素的数目(待用)
*/
int* binary(IplImage* img, int g_bi_threshold)
{
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]>g_bi_threshold) ? 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;
}
/*
功能:读入图像文件,对图像进行裁剪
@变量 img iplimage图像文件
@变量 img 裁剪后的iplimage图像文件
@jbwhite
@jbblack
@返回值 返回裁剪后的图像
*/
IplImage* Cjbsb(IplImage* img, IplImage* imgjbsb, int jbwhite, int jbblack)
{
/*定义变量*/
int i, j, 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;
}
/*
功能:计算图像的特征
@变量 imgbj 笔迹部分的图像
@返回值 计算得到的特征图像
*/
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;
// printf("--outline--");
for (j = 0; j<height; j++){
for (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;
}
/*
功能:输入图像的特征轮廓图,返回图像的特征值
@变量 imglk 输入的图像轮廓图
@变量 feature 得到的图像特征
@返回值 成功1失败0
*/
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 里面的变量
// printf("--outlinefeature--");
// 获取图像信息
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 = 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***********************
}// if
} //for j
} //for i
//****注最终特征值为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有四个字节
// printf("轮廓特征值计算完成\n");
return 0;
}
/*
功能:对单张图像的处理,最终得到一个特征值,用来计算各个图像之间的卡方距离
@变量 path 图像的物理地址
@变量 feature 图像的特征值
@返回值 处理后的图像
*/
IplImage* singlefeature(char* path, int feature[][50])
{
//定义变量
//原图
IplImage* imglk = 0; //轮廓图
IplImage* imggj = 0; //骨架图
IplImage* imgjbsb = 0; //角标识别图
IplImage* imgbj = 0; //只提取笔记部分的图像
IplImage* imgbjhf = 0; //为文字区域画上方格
IplImage* imgwzbj = 0; //为文字区域标出是否为文字(文字标记)
int height, width, step, channels;
uchar *data;
int i, j; //用于返回图像每行黑像素的个数
//int feature[50][50]={0}; //特征值初始化
IplImage* 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 = 840;
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 - 立方插值.
/*二值化*/
binary(imgbig, g_bi_threshold);
//SaveLog("singlefeature_binary\n", "D:\\HWCV\\numtxt.txt", "a");
/*裁剪识别*/
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;
}
}
/*计算骨架特征徝*/
outlinefeature(imggj, feature); //特征值占48*48的右上三角形feature调用返回
/*释放内存*/
cvReleaseImage(&imgbig);
cvReleaseImage(&img);
cvReleaseImage(&imgbj);
cvReleaseImage(&imglk);
cvReleaseImage(&imgjbsb);
cvReleaseImage(&imgbjhf);
cvReleaseImage(&imgwzbj);
cvDestroyAllWindows();
return imggj;
}
/*
功能细化之前的图像颜色处理将颜色范围转换到0-1
@变量 ip 图像的句柄
@变量 jp
@变量 lx 图象宽度
@变量 ly 图象高度
@返回值 空
*/
void beforethin(unsigned char *ip, unsigned 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;
}
}
}
/*功能:细化算法 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;
// printf("--Thinner_Rosenfeld--");
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);
}

View File

@@ -0,0 +1,99 @@
/*
头文件process.h 图像处理函数头文件
*/
#pragma once
#include "StdAfx.h"
#include "Point.h"
#include "path.h"
#include "process.h"
#include <cv.h>
#include <direct.h>
#include <io.h>
#include <iostream>
#include <math.h>
#include <malloc.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
/*全局变量*/
extern IplImage* src;
/***************************************函数原型****************************************/
int ComputeImage(vector<string> files, double bzckesa[50][50], double *wcd, int conti);
/*
功能:读入图像文件,进行二值化
@变量 img iplimage图像文件
@变量 bithro 二值化阈值
@返回值 黑像素的数目(待用)
*/
int* binary(IplImage* img, int bithro);
/*
功能:读入图像文件,对图像进行裁剪
@变量 img iplimage图像文件
@变量 img 裁剪后的iplimage图像文件
@jbwhite
@jbblack
@返回值 返回裁剪后的图像
*/
IplImage* Cjbsb(IplImage* img, IplImage* imgjbsb, int jbwhite, int jbblack);
/*
功能:计算图像的特征
@变量 imgbj 笔迹部分的图像
@返回值 计算得到的特征图像
*/
IplImage* outline(IplImage* imgbj);
/*
功能:输入图像的特征轮廓图,返回图像的特征值
@变量 imglk 输入的图像轮廓图
@变量 feature 得到的图像特征
@返回值 成功1失败0
*/
int outlinefeature(IplImage* imglk, int feature[][50]);
/*
功能:对单张图像的处理,最终得到一个特征值,用来计算各个图像之间的卡方距离
@变量 path 图像的物理地址
@变量 feature 图像的特征值
@返回值 处理后的图像
*/
IplImage* singlefeature(char* path, int feature[][50]);
/*
功能细化之前的图像颜色处理将颜色范围转换到0-1
@变量 ip 图像的句柄
@变量 jp
@变量 lx 图象宽度
@变量 ly 图象高度
@返回值 空
*/
void beforethin(unsigned char *ip, unsigned char *jp, unsigned long lx, unsigned long ly);
/*功能:细化算法 Rosenfeld细化算法用于完成对笔迹图像的股价提取
@变量 image 代表图象的一维数组
@变量 lx 图象宽度
@变量 ly 图象高度
@返回值 无返回值
*/
void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly);

View File

@@ -0,0 +1,219 @@
///*
//主函数文件segmentation.cpp 主函数的实现文件
//*/
//#include "segmentation.h"
////#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )//无界面运行
///*主函数*/
//int ComputeImage(vector<string> files, double bzckesa[50][50], double *wcd, int conti);
//int main(int argc, char* argv[])
//{
// /*变量定义*/
// string dir = "E:\\xiangmu\\Img\\imgjiaobiao\\010211100518"; //存储目录
// //string dir;
// //if (argc < 2)
// // return -1;
// //else
// // dir = argv[1];
// cout << (char*)dir.c_str() << endl;
// char record[2400] = { 0 };
// FILE* fpzz = NULL;//需要注意
// int i, ii, jj, feature[50][50][30] = { 0 }, featureall = 0;
// double featurep[50][50][30] = { 0 };
// double bzcu[50][50] = { 0 };
// double bzckesa[50][50] = { 0 };
// double wcd[30] = { 0 };
//
// int featx[50][50] = { 0 };
// int featdif[30] = { 0 };
// float maxx = 0; //最大特征值的标号与值
// int xyimgnum = 0; //嫌疑图片的数目
// char str[80]; //存储地址
//
// vector<string> suspict; //记录嫌疑图片地址
// vector<float> suspict_wcd; //嫌疑图片的wcd值
// vector<string> files; //存储该生所有考试文件路径
//
// /*读取配置文件,并配置各项参数*/
// if (!ReadConfig("D:/HWCV/config/configure.cfg"))
// {
// // SaveLog("\t配置文件读取失败\n", g_log_adr, "a");
// SaveLog("\n0\n", g_log_adr, "a");
// return 0;
// }
// char path[100] = "E:/xiangmu/Img/imgjiaobiao/";
//
//
//
// /*步骤:读取标准差文件*/
// int bzccolumns = 47;//txt文件中有47列
// vector<double *> output_bzc;
// if (!ReadScanf("D:\\HWCV\\config\\stdfile.db", bzccolumns, output_bzc))
// {
// memset(g_log_rec, 0, sizeof(g_log_rec));
//
// // SaveLog("\n读取路径D:\\HWCV\\config\\stdfile.db 的标准差文件失败!\n", g_log_adr, "a");
// SaveLog("\n0\n", g_log_adr, "a");
// return 0;
// }
//
// //开始检测
// //-------------------------------------------------------------//
// getFiles(dir.c_str(), files); //遍历当前文件夹下的所有文件
// int size = files.size();
//
// for (i = 0; i < size; i++)
// {
// // cout << ".";
// memset(str, 0, sizeof(str));
// memset(featx, 0, sizeof(featx));
// memset(bzcu, 0, sizeof(bzcu));
//
// strcpy(str, files[i].c_str());
// singlefeature(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
// }
// }/*处理完全部图片*/
//
// /*求标准差中u*/
// for (ii = 0; ii < 48; ii++)
// for (jj = ii + 1; jj < 47; jj++)
// bzcu[ii][jj] = bzcu[ii][jj] / size;
//
//
// for (ii = 0; ii < 48; ii++)//output_vector可视为二维数组;输出数组元素:
// for (jj = ii + 1; jj < 47; jj++)
// bzckesa[ii][jj] = output_bzc[ii][jj];
//
// /*求相似性即带权卡方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][g_conti] != 0 && bzckesa[ii][jj] != -1)
// wcd[i] += pow((featurep[ii][jj][i] - featurep[ii][jj][g_conti]), 2) / ((featurep[ii][jj][i] + featurep[ii][jj][g_conti])*bzckesa[ii][jj]);
//
// //标出所有有嫌疑的图像1无嫌疑的图像0
// for (i = 0; i < size; i++)
// {
// if (wcd[i] > 0.12)
// {
// xyimgnum++;
// suspict.push_back(files[i].c_str());
// suspict_wcd.push_back(wcd[i]);
// }
// }
//
// /*将结果存入log文件*/
// strcat(g_log_rec, "\n");
// memset(g_log_rec, 0, sizeof(g_log_rec));
// // strcat(g_log_rec, GetTime());
// // strcat(g_log_rec, "\t考生考号");
// strcat(g_log_rec, dir.substr(27, 22).c_str());
// strcat(g_log_rec, "\t");//图片总数为:
// char pic_num[20];
// _itoa(size, pic_num, 10);
// strcat(g_log_rec, pic_num);
// if (xyimgnum > 0)
// {
// char b[20];
// sprintf(b, "\t%d", xyimgnum);
// strcat(g_log_rec, b);
// strcat(g_log_rec, "\n");
// for (i = 0; i < xyimgnum; i++)
// {
// // cout << "嫌疑图像:" << files[i].c_str() << endl;
// strcat(g_log_rec, "\t\t\t");//\t嫌疑图像
// strcat(g_log_rec, suspict[i].c_str());
// strcat(g_log_rec, "\t");//相似度:
// float sim = (1.0 - suspict_wcd[i]) * 100;
// char a[20];
// sprintf(a, "%g", sim);
// strcat(g_log_rec, a);
// strcat(g_log_rec, "%%\n");
// }
// }
// else
// {
// // strcat(g_log_rec, "\t该考生没有嫌疑图像\n");
// strcat(g_log_rec, "\t0\n");
// // cout << "该考生无嫌疑图像!" << endl;
// }
// SaveLog(g_log_rec, g_log_adr, "a");
//
//
// /*善后*/
// suspict.clear();
// suspict_wcd.clear();
// memset(g_log_rec, 0, sizeof(g_log_rec));
// memset(feature, 0, sizeof(feature));
// memset(featurep, 0, sizeof(featurep));
// memset(bzckesa, 0, sizeof(bzckesa));
// memset(wcd, 0, sizeof(wcd));
// memset(featdif, 0, sizeof(featdif));
// files.clear();
// memset(g_log_rec, 0, sizeof(g_log_rec));
//
// /*返回值*/
// return 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;
//}

View File

@@ -0,0 +1,146 @@
/*
主函数文件segmentation.cpp 主函数的实现文件
*/
#include "segmentation.h"
//#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )//无界面运行
/*主函数*/
int main(int argc, char* argv[])
{
/*变量定义*/
string dir = "E:/xiangmu/Img/imgjiaobiao/010211100518"; //存储目录
//string dir;
//if (argc < 2)
// return -1;
//else
// dir = argv[1];
cout << (char*)dir.c_str() << endl;
char record[2400] = { 0 };
FILE* fpzz = NULL;//需要注意
int i, ii, jj, feature[50][50][30] = { 0 }, featureall = 0;
double featurep[50][50][30] = { 0 };
double bzcu[50][50] = { 0 };
double bzckesa[50][50] = { 0 };
double wcd[30] = { 0 };
int featx[50][50] = { 0 };
int featdif[30] = { 0 };
float maxx = 0; //最大特征值的标号与值
int xyimgnum = 0; //嫌疑图片的数目
vector<string> suspict; //记录嫌疑图片地址
vector<float> suspict_wcd; //嫌疑图片的wcd值
vector<string> files; //存储该生所有考试文件路径
/*读取配置文件,并配置各项参数*/
if (!ReadConfig("D:/HWCV/config/configure.cfg"))
{
// SaveLog("\t配置文件读取失败\n", g_log_adr, "a");
SaveLog("\n0\n", g_log_adr, "a");
return 0;
}
char path[100] = "E:/xiangmu/Img/imgjiaobiao/";
/*步骤:读取标准差文件*/
int bzccolumns = 47;//txt文件中有47列
vector<double *> output_bzc;
if (!ReadScanf("D:\\HWCV\\config\\stdfile.db", bzccolumns, output_bzc))
{
memset(g_log_rec, 0, sizeof(g_log_rec));
// SaveLog("\n读取路径D:\\HWCV\\config\\stdfile.db 的标准差文件失败!\n", g_log_adr, "a");
SaveLog("\n0\n", g_log_adr, "a");
return 0;
}
// cout<<"标准差:"<<endl;
for (ii = 0; ii < 48; ii++)//output_vector可视为二维数组;输出数组元素:
for (jj = ii + 1; jj < 47; jj++)
{
bzckesa[ii][jj] = output_bzc[ii][jj];
// cout<< bzckesa[ii][jj];
}
// cout<<endl;
//开始检测
//-------------------------------------------------------------//
getFiles(dir.c_str(), files); //遍历当前文件夹下的所有文件
int size = files.size();
cout << "考生文件数量" <<size<< endl;
//开始对每一张图片进行处理
for (int r = 0; r<size; r++)
{
memset(wcd, 0, sizeof(wcd));
cout<<"-对每一张图片进行处理-"<<files[r].c_str()<<endl;
ComputeImage(files, bzckesa, wcd, r);
xyimgnum = 0;
//求卡方距离的最大值
for (i = 0; i < size; i++)
{
cout << files[i].c_str()<< " " << wcd[i] << endl;
if (wcd[i]>0.12)
{
xyimgnum++;
suspict.push_back(files[i].c_str());
suspict_wcd.push_back(wcd[i]);
}
}
if (xyimgnum<3) break;
}
/*将结果存入log文件*/
strcat(g_log_rec, "\n");
memset(g_log_rec, 0, sizeof(g_log_rec));
// strcat(g_log_rec, GetTime());
// strcat(g_log_rec, "\t考生考号");
strcat(g_log_rec, dir.substr(27, 22).c_str());
strcat(g_log_rec, "\t");//图片总数为:
char pic_num[20];
_itoa(size, pic_num, 10);
strcat(g_log_rec, pic_num);
if (xyimgnum > 0)
{
char b[20];
sprintf(b, "\t%d", xyimgnum);
strcat(g_log_rec, b);
strcat(g_log_rec, "\n");
for (i = 0; i < xyimgnum; i++)
{
cout << "嫌疑图像:" << files[i].c_str() << endl;
strcat(g_log_rec, "\t\t\t");//\t嫌疑图像
strcat(g_log_rec, suspict[i].c_str());
strcat(g_log_rec, "\t");//相似度:
float sim = (1.0 - suspict_wcd[i]) * 100;
char a[20];
sprintf(a, "%g", sim);
strcat(g_log_rec, a);
strcat(g_log_rec, "%%\n");
}
}
else
{
// strcat(g_log_rec, "\t该考生没有嫌疑图像\n");
strcat(g_log_rec, "\t0\n");
cout << "该考生无嫌疑图像!" << endl;
}
SaveLog(g_log_rec, g_log_adr, "a");
/*善后*/
suspict.clear();
suspict_wcd.clear();
memset(g_log_rec, 0, sizeof(g_log_rec));
memset(feature, 0, sizeof(feature));
memset(featurep, 0, sizeof(featurep));
memset(bzckesa, 0, sizeof(bzckesa));
memset(wcd, 0, sizeof(wcd));
memset(featdif, 0, sizeof(featdif));
files.clear();
memset(g_log_rec, 0, sizeof(g_log_rec));
/*返回值*/
system("pause");
return 0;
}

View File

@@ -0,0 +1,43 @@
/*
头文件segmentation.h 主函数头文件
*/
#pragma once
#ifdef WIN32 //屏蔽VC6对STL的一些不完全支持造成
#pragma warning (disable: 4514 4786)
#endif
#include "StdAfx.h"
#include "path.h"
#include "Point.h"
#include "process.h"
using namespace std;
/*定义全局变量*/
int g_bi_threshold = 230; /* 全局变量 二值化阈值*/
double g_std_kesa[50][50]; /* 全局变量 标准差数组*/
float g_doubt_threshold = 0.12; /* 全局变量 作弊嫌疑阈值*/
string g_dir = "Y:/"; /* 全局变量 总路径的目录*/
int g_cheat_num_threshold = 0; /* 全局变量 默认作弊阈值*/
int g_conti = 1; /* 全局变量 默认作弊比较的图片*/
int g_all_img_num = 0; /* 全局变量 已鉴定的全部图片数量*/
int g_doubt_img_num = 0; /* 全局变量 已鉴定怀疑的图片数量*/
int g_all_stu_num = 0; /* 全局变量 已鉴定的全部学生数量*/
int g_doubt_stu_num = 0; /* 全局变量 已鉴定怀疑的学生数量*/
bool g_output_cmd_config = false; /*全局变量 输出参数控制*/
bool g_output_txt_config = false; /*全局变量 输出中间文件选项*/
char g_log_adr[50] = "D:/HWCV/log_ori.txt"; /*全局变量 程序日志存储地址*/
char g_log_rec[500] = { 0 }; /*全局变量 程序日志专用变量*/
char g_err_adr[50]= "D:/HWCV/err_ori.txt"; /*错误日志路径*/
/*全局变量 输出txt结果文件*/
/*全局变量 输出txt结果文件地址*/
time_t ltime;
char *srcTime=NULL;
char timeNow[32]={0};
char msg[100]={0};

View File

@@ -0,0 +1,104 @@
# Microsoft Developer Studio Project File - Name="Serve" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=Serve - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Serve.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Serve.mak" CFG="Serve - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Serve - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Serve - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Serve - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x804 /d "NDEBUG"
# ADD RSC /l 0x804 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "Serve - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x804 /d "_DEBUG"
# ADD RSC /l 0x804 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "Serve - Win32 Release"
# Name "Serve - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\seachDir.cpp
# End Source File
# Begin Source File
SOURCE=.\segmentation.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# 警告: 不能编辑或删除该工作区文件!
###############################################################################
Project: "Serve"=".\Serve.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

Binary file not shown.

View File

@@ -0,0 +1,35 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: Serve - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Users\闫帅帅\AppData\Local\Temp\RSP8D94.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/Serve.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"D:\CODE\HWCV\测试\本机测试\Serve\segmentation.cpp"
]
Creating command line "cl.exe @"C:\Users\闫帅帅\AppData\Local\Temp\RSP8D94.tmp""
Creating temporary file "C:\Users\闫帅帅\AppData\Local\Temp\RSP8D95.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /incremental:yes /pdb:"Debug/Serve.pdb" /debug /machine:I386 /out:"Debug/Serve.exe" /pdbtype:sept
".\Debug\seachDir.obj"
".\Debug\segmentation.obj"
]
Creating command line "link.exe @"C:\Users\闫帅帅\AppData\Local\Temp\RSP8D95.tmp""
<h3>Output Window</h3>
Compiling...
segmentation.cpp
c:\program files\vc\vc98\include\vector(39) : warning C4786: 'std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
c:\program files\vc\vc98\include\vector(60) : warning C4786: 'std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::~vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
Linking...
<h3>Results</h3>
Serve.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@@ -0,0 +1,44 @@
/* 程序名getFiles.c
功能:返回一个文件夹下的所有文件名
*/
#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;
}

View File

@@ -0,0 +1,52 @@
/* 程序名segmentation.c
功能:总程序:读入图像文件,分析特征,输出效果
*/
//#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include<io.h> //下面的5个用于读取文件夹下的所有文件名
#include<vector>
#include<iostream>
#include <string.h>
#include<windows.h>
#include<string.h>
using namespace std;
#ifdef WIN32 //屏蔽VC6对STL的一些不完全支持造成
#pragma warning (disable: 4514 4786)
#endif
int searchDir(char* path, vector<string> &dir);//获取目录下一层的所有文件夹
int main()
{
char path[100] = "E:/xiangmu/Img/imgjiaobiao/";
vector<string> dir; //存储目录
char* fpname = "C:/Users/闫帅帅/Desktop/result2.txt";
char record[2400] = { 0 };
FILE* fpzz = NULL;//需要注意
searchDir(path, dir);//获取filePath下的所有一级目录并存储到dir中
int size = dir.size(); //dir的大小就是学生的数量
//开始检测
//-------------------------------------------------------------//
for (int i = 0; i < size; i++)//对每一个学生目录进行循环
{
cout << dir[i].c_str() << endl;
ShellExecute(NULL, "open",
"D:\\CODE\\HWCV\\测试\\HWCV-exe测试\\Release\\HWCV.exe",
dir[i].c_str(),
NULL,
SW_SHOWNORMAL);
}
return 0;
}

View File

@@ -0,0 +1,37 @@
/* 程序名getFiles.c
功能:返回一个文件夹下的所有文件名
*/
#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) );
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}

View File

@@ -0,0 +1,38 @@
/* 程序名getFolders.c
功能:返回一个文件夹下的所有文件夹的名称
*/
#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;
}

View File

@@ -0,0 +1,65 @@
/* 程序名getFolders.c
功能:返回一个文件夹下的所有文件夹的名称
*/
#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;
/*
hFile=_findfirst(p.assign(path).append("\\*").c_str(),&fileinfo); //第一次查找 to_search???
files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
if(-1==hFile)return -1; //当前文件夹下没有子文件
printf("%s\n",fileinfo.name); //打印出找到的文件的文件名
int i=0;
while(!_findnext(hFile,&fileinfo)) //循环查找其他符合的文件,知道找不到其他的为止
{
printf("%s\n",files[i].c_str());
i++;
}
_findclose(hFile); //别忘了关闭句柄
system("pause");
return 0;
*/
int i=0;
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
//{
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;
}

View File

@@ -0,0 +1,114 @@
# Microsoft Developer Studio Project File - Name="handwriting" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=handwriting - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "handwriting.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "handwriting.mak" CFG="handwriting - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "handwriting - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "handwriting - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "handwriting - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x804 /d "NDEBUG"
# ADD RSC /l 0x804 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /machine:I386
# ADD LINK32 cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.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 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "handwriting - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x804 /d "_DEBUG"
# ADD RSC /l 0x804 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 FreeImage.lib cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "handwriting - Win32 Release"
# Name "handwriting - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\getFiles.cpp
# End Source File
# Begin Source File
SOURCE=.\getFloders.cpp
# End Source File
# Begin Source File
SOURCE=.\searchDir.cpp
# End Source File
# Begin Source File
SOURCE=.\segmentation.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# 警告: 不能编辑或删除该工作区文件!
###############################################################################
Project: "handwriting"=.\handwriting.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

Binary file not shown.

View File

@@ -0,0 +1,38 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: handwriting - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Users\闫帅帅\AppData\Local\Temp\RSP9995.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/handwriting.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"D:\CODE\HWCV\测试\获取图像文件\segmentation.cpp"
]
Creating command line "cl.exe @"C:\Users\闫帅帅\AppData\Local\Temp\RSP9995.tmp""
Creating temporary file "C:\Users\闫帅帅\AppData\Local\Temp\RSP9996.tmp" with contents
[
FreeImage.lib cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.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 /nologo /subsystem:console /incremental:yes /pdb:"Debug/handwriting.pdb" /debug /machine:I386 /out:"Debug/handwriting.exe" /pdbtype:sept
".\Debug\getFiles.obj"
".\Debug\getFloders.obj"
".\Debug\searchDir.obj"
".\Debug\segmentation.obj"
]
Creating command line "link.exe @"C:\Users\闫帅帅\AppData\Local\Temp\RSP9996.tmp""
<h3>Output Window</h3>
Compiling...
segmentation.cpp
D:\CODE\HWCV\测试\获取图像文件\segmentation.cpp(63) : warning C4508: 'main' : function should return a value; 'void' return type assumed
c:\program files\vc\vc98\include\vector(39) : warning C4786: 'std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
c:\program files\vc\vc98\include\vector(60) : warning C4786: 'std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::~vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
Linking...
<h3>Results</h3>
handwriting.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@@ -0,0 +1,44 @@
/* 程序名getFiles.c
功能:返回一个文件夹下的所有文件名
*/
#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;
}

View File

@@ -0,0 +1,63 @@
/* 程序名segmentation.c
功能:总程序:读入图像文件,分析特征,输出效果
*/
//#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include<io.h> //下面的5个用于读取文件夹下的所有文件名
#include<vector>
#include<iostream>
#include <string.h>
#include<windows.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、读取文件名下所有文件名
int getFolders(string path, vector<string>& files );//11、读取文件名下所有文件夹的名称
int searchDir(char* path, vector<string> &dir);//获取目录下一层的所有文件夹
int main()
{
char path[100] = "E:/xiangmu/Img/imgjiaobiao/";
vector<string> dir; //存储目录
int size_dir,num_dir;
char* fpname= "C:/Users/闫帅帅/Desktop/result2.txt";
char record[2400]={0};
FILE* fpzz=NULL;//需要注意
searchDir(path, dir);//获取filePath下的所有一级目录并存储到dir中
size_dir=dir.size(); //dir的大小就是学生的数量
//开始检测
//-------------------------------------------------------------//
for(num_dir=0;num_dir<size_dir;num_dir++)//对每一个学生目录进行循环
{
int i=0;
vector<string> files; //存储文件路径
getFiles(dir[num_dir].c_str(), files ); //遍历当前文件夹下的所有文件
int size=files.size();
cout<<"numdir: "<<num_dir<<" size: "<<size<<endl;
//开始对每一张图片进行处理
//------------------------------------------------------//
for (i = 0;i < size;i++) cout<<"\t"<<files[i].c_str()<<endl;
cout<<endl;
}
}

View File

@@ -0,0 +1,105 @@
/* 程序名Cjbsb.c
功能:读入图像文件,甄别图像的角标
参数设置:
img 大图
imgjbsb 角标图像头
jbwhite 未知参数1
jbblack 未知参数2
【返回文字的笔迹部分】
注意:这个方法不行,另外一个号的方法:取一个方块,移动方块,确定方块中的样子,如果有横线或者数显就确定为脚标
*/
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
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;
//1、 获取图像信息
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;
//----------------------------------------//
//2、找脚标的位置
//----------------------------------------//
for(i=0;i<height/3;i++){
for(j=0;j<width/5;j++){
sumjb1=0;
for(ii=0;ii<=14;ii++) //计算特征点的下侧14与右侧14的白点数目(是因为脚标就是14的长度吧)
sumjb1=sumjb1+imgjbsbdata[(i+ii)*step+j*channels];//下侧14列的单点的白点数目
for(jj=0;jj<=14;jj++)
sumjb1=sumjb1+imgjbsbdata[i*step+(j+jj)*channels];//右侧14行的单点的白点数目
if(sumjb1<=255*jbwhite){ //jbwhite为允许角标上白点数第一次提取
sumjb2=0;
for(ii=i+2;ii<i+12;ii++)
for(jj=j+2;jj<j+12;jj++){
if(imgjbsbdata[ii*step+jj*channels]>=200)
sumjb2=sumjb2+imgjbsbdata[ii*step+jj*channels];
}
if(sumjb2>=255*(100-jbblack)){ //允许角标内黑点数,第二次提取
jbi=i;//脚标位置
jbj=j;
for(ii=i-2;ii<i+22;ii=ii+2) //标出位置
for(jj=j-2;jj<j+22;jj=jj+2){
imgjbsbdata[ii*step+jj*channels]=0;
}
brklab=1;
break;
}
}
}
if(1==brklab){
brklab=0;break;//退出标记
}
}
if(jbi==0 && jbj==0)
{
// jbi=142;
// jbj=25;
jbi=0;
jbj=0;
printf("\t\t\t甄别图像的角标失败,使用设定值Cjbsb角标识别\n");
}
cout<<"JB:"<<jbi<<" "<<jbj<<endl;
//----------------------------------------//
//3、以角标为起点进行裁剪与画框
//----------------------------------------//
// CvSize jbcjsize=cvSize(835,165); //角标裁剪框的大小宽为835象素高为165象素
CvSize jbcjsize=cvSize(833, 476);
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<476;i++){
for(j=0;j<833;j++){
imgjbcjdata[i*jbcjstep+j*jbcjchannels]=data[(i+jbi)*step+(j+jbj)*channels];
}
}
//此处是yss进行注释没发现有什么用处
for(i=0;i<476;i=i+2){
imgjbsbdata[(i+jbi)*step+jbj*channels]=0;
imgjbsbdata[(i+jbi)*step+(jbj+833)*channels]=0;
}
for(j=0;j<833;j=j+2){
imgjbsbdata[jbi*step+(j+jbj)*channels]=0;
imgjbsbdata[(jbi+476)*step+(j+jbj)*channels]=0;
}
return imgjbcj;
}

View 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;
} */

View File

@@ -0,0 +1,9 @@
class Point{
private:
public:
int x;
int y;
void setpoint(int a,int b){x=a;y=b;}
};

View File

@@ -0,0 +1,327 @@
//**************************************************************************
//Thinner.cpp
//细化算法实现文件
//**************************************************************************
//#include "StdAfx.h"
#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;
}
}
}
/////////////////////////////////////////////////////////////////////////
//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;
}
*/

View 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);

View File

@@ -0,0 +1,46 @@
/* 程序名binary.c
功能:读入图像文件,进行二值化
*/
#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;
}

View File

@@ -0,0 +1,37 @@
/* 程序名getFiles.c
功能:返回一个文件夹下的所有文件名
*/
#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) );
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}

View File

@@ -0,0 +1,38 @@
/* 程序名getFolders.c
功能:返回一个文件夹下的所有文件夹的名称
*/
#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;
}

View File

@@ -0,0 +1,65 @@
/* 程序名getFolders.c
功能:返回一个文件夹下的所有文件夹的名称
*/
#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;
/*
hFile=_findfirst(p.assign(path).append("\\*").c_str(),&fileinfo); //第一次查找 to_search???
files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
if(-1==hFile)return -1; //当前文件夹下没有子文件
printf("%s\n",fileinfo.name); //打印出找到的文件的文件名
int i=0;
while(!_findnext(hFile,&fileinfo)) //循环查找其他符合的文件,知道找不到其他的为止
{
printf("%s\n",files[i].c_str());
i++;
}
_findclose(hFile); //别忘了关闭句柄
system("pause");
return 0;
*/
int i=0;
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
//{
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;
}

View File

@@ -0,0 +1,27 @@
/*程序名getType.c
功能:读入图像文件名,得到图像类型
*/
#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;
}

View 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;
}

View File

@@ -0,0 +1,146 @@
# Microsoft Developer Studio Project File - Name="handwriting" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=handwriting - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "handwriting.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "handwriting.mak" CFG="handwriting - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "handwriting - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "handwriting - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "handwriting - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x804 /d "NDEBUG"
# ADD RSC /l 0x804 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /machine:I386
# ADD LINK32 cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.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 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "handwriting - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x804 /d "_DEBUG"
# ADD RSC /l 0x804 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 FreeImage.lib cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "handwriting - Win32 Release"
# Name "handwriting - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\binary.cpp
# End Source File
# Begin Source File
SOURCE=.\Cjbsb.cpp
# End Source File
# Begin Source File
SOURCE=.\getFiles.cpp
# End Source File
# Begin Source File
SOURCE=.\getFloders.cpp
# End Source File
# Begin Source File
SOURCE=.\getType.cpp
# End Source File
# Begin Source File
SOURCE=.\gif2ipl.cpp
# End Source File
# Begin Source File
SOURCE=.\read_scanf.cpp
# End Source File
# Begin Source File
SOURCE=.\searchDir.cpp
# End Source File
# Begin Source File
SOURCE=.\segmentation.cpp
# End Source File
# Begin Source File
SOURCE=.\singlefeature.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\Cword.h
# End Source File
# Begin Source File
SOURCE=.\Point.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# 警告: 不能编辑或删除该工作区文件!
###############################################################################
Project: "handwriting"=.\handwriting.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,49 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: handwriting - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Users\闫帅帅\AppData\Local\Temp\RSP9F62.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/handwriting.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"D:\CODE\HWCV\测试\转换图像文件到jpg\segmentation.cpp"
]
Creating command line "cl.exe @"C:\Users\闫帅帅\AppData\Local\Temp\RSP9F62.tmp""
Creating temporary file "C:\Users\闫帅帅\AppData\Local\Temp\RSP9F63.tmp" with contents
[
FreeImage.lib cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.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 /nologo /subsystem:console /incremental:yes /pdb:"Debug/handwriting.pdb" /debug /machine:I386 /out:"Debug/handwriting.exe" /pdbtype:sept
".\Debug\binary.obj"
".\Debug\Cjbsb.obj"
".\Debug\getFiles.obj"
".\Debug\getFloders.obj"
".\Debug\getType.obj"
".\Debug\gif2ipl.obj"
".\Debug\read_scanf.obj"
".\Debug\searchDir.obj"
".\Debug\segmentation.obj"
".\Debug\singlefeature.obj"
]
Creating command line "link.exe @"C:\Users\闫帅帅\AppData\Local\Temp\RSP9F63.tmp""
<h3>Output Window</h3>
Compiling...
segmentation.cpp
d:\code\hwcv\测试\转换图像文件到jpg\segmentation.cpp(43) : warning C4101: 'end' : unreferenced local variable
d:\code\hwcv\测试\转换图像文件到jpg\segmentation.cpp(44) : warning C4101: 'cost' : unreferenced local variable
d:\code\hwcv\测试\转换图像文件到jpg\segmentation.cpp(60) : warning C4101: 'ii' : unreferenced local variable
d:\code\hwcv\测试\转换图像文件到jpg\segmentation.cpp(60) : warning C4101: 'jj' : unreferenced local variable
d:\code\hwcv\测试\转换图像文件到jpg\segmentation.cpp(60) : warning C4101: 'j' : unreferenced local variable
d:\code\hwcv\测试\转换图像文件到jpg\segmentation.cpp(83) : warning C4101: 'x' : unreferenced local variable
c:\program files\vc\vc98\include\vector(39) : warning C4786: 'std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
c:\program files\vc\vc98\include\vector(60) : warning C4786: 'std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::~vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >' : identifier was truncated to '255' characters in the debug information
Linking...
<h3>Results</h3>
handwriting.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@@ -0,0 +1,46 @@
/* 程序名outline.c
功能:输入文字图像。得到相应的轮廓图
*/
#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;
}

View File

@@ -0,0 +1,262 @@
/* 程序名outline.c
功能:输入文字另外由于轮廓图像。返回相应的轮廓特征值
*/
#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=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;
}

View File

@@ -0,0 +1,26 @@
// 功能将filename 中的数据共cols列读取到_vector中_vector可视为二维数组
#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 *ptr=new double[cols];
for(i=0;i<cols;i++)
{ //读取数据存在_vector[cols]中
if(EOF==fscanf(fp,"%lf",&ptr[i])){flag=false;break;};
if(EOF==fgetc(fp)){flag=false;i++;break;}
}
if(cols==i) _vector.push_back(ptr);
}
fclose(fp);
return 1;
}

View File

@@ -0,0 +1,44 @@
/* 程序名getFiles.c
功能:返回一个文件夹下的所有文件名
*/
#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;
}

View File

@@ -0,0 +1,94 @@
/* 程序名segmentation.c
功能:总程序:读入图像文件,分析特征,输出效果
*/
//#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include "Point.h"
#include "FreeImage.h" //用于读gif的图像,将gif图像转换为png
#include<io.h> //下面的5个用于读取文件夹下的所有文件名
#include<vector>
#include<iostream>
#include <string.h>
#include<windows.h> //用于弹出提示框,,,切记!当调用<windows.h>时不要调用MFCAfx.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、读取文件名下所有文件名
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 searchDir(char* path, vector<string> &dir);//获取目录下一层的所有文件夹
IplImage* Cjbsb(IplImage* img,IplImage* imgjbsb,int jbwhite,int jbblack);//4、图像角标识别
IplImage* gif2ipl(const char* filename); //1、读取gif的外部函数
IplImage* singlefeature(char* path,int feature[ ][50],int flag);//10、得出单个文件的特征值
int pos_x=0,pos_y=0;
bool pos_flag=false;
IplImage* src;
int picAll=0,picSus=0;
int main()
{
time_t start ,end ;//计时
double cost; time(&start);
//定义变量
//------------------------------------------------------//
char path[100] = "D:\\xiangmu\\Img\\imgjiaobiao3\\";
vector<string> dir; //存储目录
int conti=1; //对比图像的标号
int size_dir,num_dir;
searchDir(path, dir);//获取filePath下的所有一级目录并存储到dir中
size_dir=dir.size(); //dir的大小就是学生的数量
//开始转换
//-------------------------------------------------------------//
for(num_dir=0;num_dir<size_dir;num_dir++)//对每一个学生目录进行循环
{
int size,i,j,ii,jj; //通用变量
char str[80]; //存储地址
int featx[30][50];
vector<string> files; //存储文件路径
getFiles(dir[num_dir].c_str(), files ); //遍历当前文件夹下的所有文件
//输出
printf("\n第%d目录%s",num_dir,dir[num_dir].c_str());
size = files.size(); //图像的数目
//输出
printf("\t个数:%d\t",size);
//开始对每一张图片进行处理
//------------------------------------------------------//
int flag=1;
for (i = 0;i < size;i++)
{
memset(str,0,sizeof(str));
strcpy(str,files[i].c_str());
try
{
singlefeature(str,featx,flag);//str图片路径 featx图片特征值存在变量中featx中
}catch(int x)
{
}
flag=0;
}
}
return 0;
}

View File

@@ -0,0 +1,135 @@
/* 程序名singlefeature.c
功能:分总程序:读入图像文件,得出单个文件的特征值
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include "Point.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],int flag){
//定义变量
IplImage* img = 0; //原图
IplImage* imglk = 0; //轮廓图
IplImage* imggj = 0; //骨架图
IplImage* imgjbsb = 0; //角标识别图
IplImage* imgbj = 0; //只提取笔记部分的图像
char imgtype[10]; //判断图像类型
int height,width,step,channels;
uchar *data;
int *black; //用于返回图像每行黑像素的个数
//int feature[50][50]={0}; //特征值初始化
getType(path, imgtype);
if(strcmp(".gif", imgtype) == 0)
{
IplImage* Iplimg=gif2ipl(path); //gif 转 rgb 三维
img=cvCreateImage(cvGetSize(Iplimg),Iplimg->depth,1);
cvCvtColor(Iplimg,img,CV_RGB2GRAY); //rgb 转灰度
cvReleaseImage(&Iplimg); //释放临时图像的内存
cvFlip(img,NULL, 0); //由于得到的灰度图是翻转的,所以再翻转回来
}
else if(strcmp(".jpg", imgtype) == 0 || strcmp(".png", imgtype) == 0)
img=cvLoadImage(path,0);
else
return NULL;
if(!img)
{
printf("Could not load image file: %s\n",path);
exit(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<850){
scale=(float)850/width;
dst_cvsize.width=850;
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); //返回文字的笔迹部分
//存储裁剪后的图像
//D:/xiangmu/Img/imgjiaobiao/010211100059x/0359.gif
char isavePath[200]="E";
//此处需要新建一个新建文件夹的选项
string name=path;
strcat(isavePath, name.substr(1, 39).c_str());
string md="mkdir ";
md += isavePath;
//组合出新名字
strcat(isavePath, name.substr(40, 5).c_str());
strcat(isavePath, ".jpg");
//创建文件夹
if(flag) system(md.c_str());
//保存图像
cvSaveImage(isavePath,imgbj);
cvReleaseImage(&imgbig);
cvReleaseImage(&img );
cvReleaseImage(&imgbj );
cvDestroyAllWindows();
cout<<".";
return imggj;
}

View File

@@ -0,0 +1,136 @@
/* 程序名Cjbsb.c
功能:读入只有文字区域的图像文件,将文字划分开来
输入参数:只有文字区域的图像文件,行阈值,列阈值,划格后的行标与列标
默认hthro=10wthro=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;
}

View 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;
}