twain2/SupperScanImageMTF.cpp

247 lines
9.4 KiB
C++
Raw Blame History

#include "stdafx.h"
#include "SupperScanImageMTF.h"
#include "math.h"
CSupperScanImageMTF::CSupperScanImageMTF(void)
{
memset(&st_im, 0, sizeof(IMAGE_MTF));
blank_bk = NULL;
cur_image = NULL;
}
CSupperScanImageMTF::~CSupperScanImageMTF(void)
{
memset(&st_im, 0, sizeof(IMAGE_MTF));
delete[]blank_bk[0];
delete[]blank_bk;
delete[]cur_image[0];
delete[]cur_image;
}
/// <summary>
/// return the state of the image whether it is blank.
/// </summary>
bool CSupperScanImageMTF::GetImageBlankFlag()
{
return is_blank;
}
/// <summary>
/// Initialize the information needed to estimate an image.
/// set the size of the image, the starting coordinate.
/// set the parameters related to the dafault values(10,10,1.0,76).
/// If the initialization finished,return true and the b_init_image_info_flg will be set to true;
/// otherwise return false.
/// </summary>
/// <param name="n_image_width","n_image_height"> the width ,height of the input image.</param>
/// <param name=" n_start_x"," n_start_y">the starting position on the width and the height direction.</param>
bool CSupperScanImageMTF::InitMTFImageInfo(INT n_image_width, INT n_image_height, INT n_start_x, INT n_start_y)
{
if (st_im.b_init_image_info_flg)
return TRUE;
if (n_image_width < 0 || n_image_height < 0 || n_start_x < 0 || n_start_y < 0)
{
return FALSE;
}
if ((n_image_width - n_start_x) < width_half_count * 2 || (n_image_height - n_start_y) < height_half_count * 2)
{
return FALSE;
}
memset(&st_im, 0, sizeof(IMAGE_MTF));
st_im.st_image_size.n_image_height = n_image_height;
st_im.st_image_size.n_image_width = n_image_width;
st_im.st_image_size.n_image_start_x = n_start_x;
st_im.st_image_size.n_image_start_y = n_start_y;
FLOAT f_x = (n_image_width - n_start_x)*1.0F / (width_half_count * 2);
FLOAT f_y = (n_image_height - n_start_y)*1.0F / (height_half_count * 2);
st_im.n_mtf_image_width = (INT)f_x;
st_im.n_mtf_image_height = (INT)f_y;
//SetSkipBlankPara(10, 10, 1, 76);
st_im.b_init_image_info_flg = TRUE;
return TRUE;
}
/// <summary>
/// estimate the input image whehter it is blank or not
/// set the size of the image, the starting coordinate;
/// set the parameters(INT w_half_count, INT h_half_count, INT f_range, INT thres) needed to estimate
/// an image blank to the dafault values(10,10,1.0,76).
/// allocate space for the two-dimensional array which will contain the computed variances of each region of the input image.
/// allocate space for the two-dimensional array which will contain the computed variances of each region of a blank image.
/// initialize both of the two arrays to 0.0.
/// </summary>
/// <param name="n_image_width"> the width of the input image.</param>
/// <param name="n_image_height">the height of the input image.</param>
/// <param name=" n_start_x">the starting position on the width direction .</param>
/// <param name=" n_start_y">the start position on the height direction.</param>
bool CSupperScanImageMTF::IsImageBlank(PBYTE p_image_data, INT n_image_width, INT n_image_height, DWORD dw_bit_color)
{
bool blank = false;
if (p_image_data == NULL && n_image_width != st_im.st_image_size.n_image_height && n_image_height != st_im.st_image_size.n_image_width)
return blank;
if (!st_im.b_init_image_info_flg) {
return blank;
}
INT n_w = 0;
INT n_h = 0;
INT n_x = 0;
INT n_y = 0;
DWORD dw_all_r = 0;
DWORD dw_all_g = 0;
DWORD dw_all_b = 0;
INT f_r_average = 0.0F;
INT f_g_average = 0.0F;
INT f_b_average = 0.0F;
DWORD dw_src_image_line_bytes = (n_image_width * dw_bit_color + 31) / 32 * 4;
if (dw_bit_color >= 8 && dw_bit_color % 8 == 0 && dw_bit_color != 16)
{
DWORD dw_bit_pixel = dw_bit_color >> 3;
DWORD dwMTF_RECT_HEIGHT = n_image_height / (height_half_count * 2);
DWORD dwMTF_RECT_WIDTH = n_image_width / (width_half_count * 2);
PBYTE p_data_ls = NULL;
DWORD dw_data_pos_h_ls = 0;
DWORD dw_data_pos_w_ls = 0;
for (n_h = 0; n_h < height_half_count * 2; n_h++)
{
for (n_w = 0; n_w < width_half_count * 2; n_w++)
{
dw_all_r = 0;
dw_all_g = 0;
dw_all_b = 0;
p_data_ls = p_image_data + n_h * dwMTF_RECT_HEIGHT * dw_src_image_line_bytes + n_w * dwMTF_RECT_WIDTH * dw_bit_pixel;
dw_data_pos_h_ls = 0;
for (n_y = 0; n_y < dwMTF_RECT_HEIGHT; n_y++)
{
dw_data_pos_w_ls = 0;
for (n_x = 0; n_x < dwMTF_RECT_WIDTH; n_x++)
{
if (dw_bit_pixel == 1) {
dw_all_g += *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls);
}
else {
dw_all_b += *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls + 0);
dw_all_g += *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls + 1);
dw_all_r += *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls + 2);
}
dw_data_pos_w_ls += dw_bit_pixel;
}
dw_data_pos_h_ls += dw_src_image_line_bytes;
}
if (dw_bit_pixel == 1) {
f_r_average = f_g_average = f_b_average = dw_all_g / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH);
}
else {
f_b_average = dw_all_b / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH);
f_g_average = dw_all_g / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH);
f_r_average = dw_all_r / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH);
}
dw_all_r = 0;
dw_all_g = 0;
dw_all_b = 0;
p_data_ls = p_image_data + n_h * dwMTF_RECT_HEIGHT * dw_src_image_line_bytes + n_w * dwMTF_RECT_WIDTH * dw_bit_pixel;
dw_data_pos_h_ls = 0;
DWORD dw_tmp = 0x0L;
for (n_y = 0; n_y < dwMTF_RECT_HEIGHT; n_y++)
{
dw_data_pos_w_ls = 0;
for (n_x = 0; n_x < dwMTF_RECT_WIDTH; n_x++)
{
if (dw_bit_pixel == 1) {
dw_tmp = *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls) - f_g_average;
dw_all_g += (DWORD)dw_tmp * dw_tmp;
}
else {
dw_tmp = *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls + 0) - f_b_average;
dw_all_b += dw_tmp * dw_tmp;
dw_tmp = *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls + 1) - f_g_average;
dw_all_g += dw_tmp * dw_tmp;
dw_tmp = *(p_data_ls + dw_data_pos_h_ls + dw_data_pos_w_ls + 2) - f_r_average;
dw_all_r += dw_tmp * dw_tmp;
}
dw_data_pos_w_ls += dw_bit_pixel;
}
dw_data_pos_h_ls += dw_src_image_line_bytes;
}
if (dw_bit_pixel == 1) {
cur_image[n_w][n_h].f_r_mtf = cur_image[n_w][n_h].f_g_mtf = cur_image[n_w][n_h].f_b_mtf = (INT)sqrt((dw_all_g*1.0F) / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH - 1));
}
else {
cur_image[n_w][n_h].f_r_mtf = (INT)sqrt((dw_all_r*1.0F) / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH - 1));
cur_image[n_w][n_h].f_g_mtf = (INT)sqrt((dw_all_g*1.0F) / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH - 1));
cur_image[n_w][n_h].f_b_mtf = (INT)sqrt((dw_all_b*1.0F) / (dwMTF_RECT_HEIGHT * dwMTF_RECT_WIDTH - 1));
}
}
}
}
else
{
return blank;
}
st_im.n_cur_precent_rect_count = 0;
for (n_w = 0; n_w < width_half_count * 2; n_w++)
{
for (n_h = 0; n_h < height_half_count * 2; n_h++)
{
if (CMP_FLOAT_RANGLE(blank_bk[n_w][n_h].f_r_mtf, float_range, cur_image[n_w][n_h].f_r_mtf) && \
CMP_FLOAT_RANGLE(blank_bk[n_w][n_h].f_g_mtf, float_range, cur_image[n_w][n_h].f_g_mtf) && \
CMP_FLOAT_RANGLE(blank_bk[n_w][n_h].f_b_mtf, float_range, cur_image[n_w][n_h].f_b_mtf))
{
st_im.n_cur_precent_rect_count++;
}
}
}
st_im.n_cur_precent_rect_count = (INT)((st_im.n_cur_precent_rect_count)*1.0F / (height_half_count * width_half_count * 4) * 100);
if (st_im.n_cur_precent_rect_count >= threshold)//<2F><><EFBFBD><EFBFBD>
{
blank = true;
is_blank = blank;
}
return blank;
}
/// <summary>
/// Set the parameters needed to estimate whether an image is blank or not.
/// allocate space for the two two-dimensional array which will contain the computed variances of each region of the input image and a blank image respectively.
/// initialize both of the two arrays to 0.0.
/// If the setting finished,return true; otherwise return false.
/// </summary>
/// <param name=" w_half_count","h_half_count"> half of the number of blocks divided on the width and height of the input image.</param>
/// <param name="f_range">the float range of variance compared with 0,because the variances of regions of an blank image are all 0.</param>
/// <param name="thres">the percent of regions whose variance is in the floating range.</param>
bool CSupperScanImageMTF::SetSkipBlankPara(INT w_half_count, INT h_half_count, INT f_range, INT thres) {
if (w_half_count <= 0 || w_half_count >= (st_im.st_image_size.n_image_width >> 1) || h_half_count <= 0 || h_half_count >= st_im.st_image_size.n_image_height >> 1) {
return FALSE;
}
if (f_range < 0 || thres < 0 || thres >100) {
return FALSE;
}
this->width_half_count = w_half_count;
this->height_half_count = h_half_count;
this->float_range = f_range;
this->threshold = thres;
if (blank_bk != NULL) {
delete[]blank_bk[0];
delete[]blank_bk;
}
if (cur_image != NULL) {
delete[]cur_image[0];
delete[]cur_image;
}
blank_bk = new IMAGE_RECT_MTF *[width_half_count * 2];//<2F><><EFBFBD><EFBFBD>mtf
cur_image = new IMAGE_RECT_MTF *[width_half_count * 2];//<2F><>ǰ֡<C7B0><D6A1>MTF
blank_bk[0] = new IMAGE_RECT_MTF[width_half_count *height_half_count * 4];
cur_image[0] = new IMAGE_RECT_MTF[width_half_count *height_half_count * 4];
for (int i = 1; i < width_half_count * 2; ++i) {
blank_bk[i] = blank_bk[i - 1] + height_half_count * 2;
cur_image[i] = cur_image[i - 1] + height_half_count * 2;
}
IMAGE_RECT_MTF bk = { 0.0f, 0.0f, 0.0f };
for (int i = 0; i < width_half_count * 2; ++i) {
for (int j = 0; j < height_half_count * 2; ++j) {
blank_bk[i][j] = bk;
cur_image[i][j] = bk;
}
}
return TRUE;
}