📄 vlimageproc.cpp
字号:
// vlImageProc.cpp: implementation of the CvlImageProc class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "airImg.h"
#include "vlImageProc.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CvlImageProc::CvlImageProc()
{
for(int i=0; i<12; i++)
{
objectcoordinates[i][0]=0;
objectcoordinates[i][1]=0;
objectr[i]=0;
}
objectnum=0;
}
CvlImageProc::~CvlImageProc()
{
}
/* given a RGB picture, return a gray level one */
int CvlImageProc::vlRgb2Gray(CvlImage *src, CvlWindow *window, CvlImage *dest)
{
int i, j;
int index, width;
int x1, x2, y1, y2;
vlPixel *input;
vlPixel *output;
/* verify parameters */
if ((!src) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != RGB) {
MessageBox(NULL,"src image is not RGB\n","warnning",MB_OK);
return (-1); /* failure */
}
/* initialize the new picture */
/*
if (0 > vlImageInit (dest, GRAY, src->width, src->height)) {
MessageBox(NULL,"could not initialize dest image\n","warnning",MB_OK);
return (-1); / * failure * /
}*/
/* temp variables to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
input = src->pixel;
output = dest->pixel;
/* proceed to conversion */
for (j=y1; j<y2; j++) {
for (i=x1; i<x2; i++) {
index = VL_RGB_PIXEL * (j*width + i);
/* average RGB into graylevel */
output[index/VL_RGB_PIXEL] =
(unsigned char)(input[index]*0.30 + input[index+1]*0.59 + input[index+2]*0.11) ;
}
}
return (0); /* success */
}
int CvlImageProc::vlRgb2Hsi(CvlImage *src, CvlWindow *window, CvlImage *dest)
#ifdef USE_INT_MATH
/* the following uses integer math */
{
int i, j;
int r, g, b;
int index, width;
int x1, x2, y1, y2;
vlPixel *input;
vlPixel *output;
int min, max, delta, sum;
int vl43 = VL_PIXEL_MAXVAL * 4 / 3;
int vl3 = VL_PIXEL_MAXVAL / 3;
int vl53 = VL_PIXEL_MAXVAL * 5 / 3;
int vl23 = VL_PIXEL_MAXVAL * 2 / 3;
/* verify parameters */
if ((!src) || (!window) || (!dest))
{
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != RGB)
{
MessageBox(NULL,"src image is not RGB\n","warnning",MB_OK);
return (-1); /* failure */
}
/* temporary variable to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
output = dest->pixel;
input = src->pixel;
/* proceed to conversion */
for (j=y1; j<y2; j++) {
for (i=x1; i<x2; i++){
/* From Foley & vanDam, "Computer Graphics: Principles and Practice",
* Addison-Wesley, 2nd edition, 1990, p. 595 (Fig 13.36)
*/
/* get a point */
index = VL_RGB_PIXEL * (j*width + i);
r = input[index++]; /* 0-255 */
g = input[index++]; /* 0-255 */
b = input[index]; /* 0-255 */
max = max(r, g);
max = max(max, b);
min = min(r, g);
min = min(min, b);
sum = min+max;
/*
* LIGHTNESS
* scale lightness [0,255] to [0,VL_PIXEL_MAXVAL] and output
*/
output[index--] = (vlPixel) (VL_PIXEL_MAXVAL * sum / 510);
/* achromatic case (color is a grey) */
if (max == min){
output[index--] = 0; /* saturation */
output[index] = 0; /* hue is "undefined", but set to 0 */
}
/* chromatic case */
else {
delta = max - min;
/*
* SATURATION
* scale saturation [0,255] to [0,VL_PIXEL_MAXVAL] and output
*/
if (sum < 255) { /* bottom cone (dark) */
output[index--] = (vlPixel)
(VL_PIXEL_MAXVAL * delta / sum);
}
else { /* top cone (bright) */
output[index--] = (vlPixel)
(VL_PIXEL_MAXVAL * delta / (510-sum));
}
/*
* HUE
* scale hue [0,360] to [0,VL_PIXEL_MAXVAL] and output
* note: rounding error if VL_PIXEL_MAXVAL < 360 (i.e., vlPixel=8-bit)
*/
if (r == max) { /* color is between yellow and magenta */
if (g < b) {
output[index] = (vlPixel)
(VL_PIXEL_MAXVAL * (g-b) / (delta * 6) + VL_PIXEL_MAXVAL);
}
else {
output[index] = (vlPixel)
(VL_PIXEL_MAXVAL * (g-b) / (delta * 6));
}
}
else if (g == max) { /* color is between cyan and yellow */
if ((2*delta) < (b-r)) {
output[index] = (vlPixel)
(VL_PIXEL_MAXVAL * (b-r) / (delta * 6) + vl43);
}
else {
output[index] = (vlPixel)
(VL_PIXEL_MAXVAL * (b-r) / (delta * 6) + vl3);
}
}
else if (b == max) { /* color is between magenta and cyan */
if ((4*delta) < (r-g)) {
output[index] = (vlPixel)
(VL_PIXEL_MAXVAL * (r-g) / (delta * 6) + vl53);
}
else {
output[index] = (vlPixel)
(VL_PIXEL_MAXVAL * (r-g) / (delta * 6) + vl23);
}
}
else {
MessageBox(NULL, "Problem with hue\n", "warnning", MB_OK);
output[index] = 0;
}
} /* end chromatic */
}
}
return (0); /* success */
}
#else
/* the following uses floating point math */
{
int i, j;
float r, g, b;
int index, width;
int x1, x2, y1, y2;
float hue, saturation, lightness;
vlPixel *input;
vlPixel *output;
float min, max, delta, sum;
/* verify parameters */
if ((!src) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != RGB) {
MessageBox(NULL,"src image is not RGB\n","warnning",MB_OK);
return (-1); /* failure */
}
/* temporary variable to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
output = dest->pixel;
input = src->pixel;
/* proceed to conversion */
for (j=y1; j<y2; j++) {
for (i=x1; i<x2; i++){
/* From Foley & vanDam, "Computer Graphics: Principles and Practice",
* Addison-Wesley, 2nd edition, 1990, p. 595 (Fig 13.36)
*/
/* get a point */
index = VL_RGB_PIXEL * (j*width + i);
r = (float) input[index] / 255.0f; /* 0-1 */
g = (float) input[index+1] / 255.0f; /* 0-1 */
b = (float) input[index+2] / 255.0f; /* 0-1 */
max = max(r, g);
max = max(max, b);
min = min(r, g);
min = min(min, b);
/*
* LIGHTNESS
*/
lightness = (min+max) / 2.0f;
/* achromatic case (because r=g=b) */
if (max == min) {
saturation = 0;
hue = 0; /* hue is undefined */
}
/* chromatic case */
else {
delta = max - min;
sum = max + min;
/*
* SATURATION
*/
if (lightness < 0.5f) { /* bottom cone (dark) */
saturation = delta / sum;
}
else { /* top cone (bright) */
saturation = delta / (2.0f - sum);
}
/*
* HUE
*/
if (r == max) { /* color is between yellow and magenta */
hue = (g-b) / delta;
}
else if (g == max) { /* color is between cyan and yellow */
hue = 2 + (b-r) / delta;
}
else if (b == max) { /* color is between magenta and cyan */
hue = 4 + (r-g) / delta;
}
else {
MessageBox(NULL, "Problem with hue\n", "warnning", MB_OK);
hue = 0;
}
hue *= 60.0;
if (hue < 0) {
hue += 360;
}
} /* end chromatic */
/* scale hue [0,360] to [0,VL_PIXEL_MAXVAL] and output
* note: rounding error if VL_PIXEL_MAXVAL < 360 (i.e., vlPixel=8-bit)
*/
output[index] = (vlPixel) (VL_PIXEL_MAXVAL * hue / 360.0f + 0.5f);
/* scale saturation [0,1] to [0,VL_PIXEL_MAXVAL] and output */
output[index+1] = (vlPixel) (VL_PIXEL_MAXVAL * saturation + 0.5f);
/* scale lightness [0,1] to [0,VL_PIXEL_MAXVAL] and output */
output[index+2] = (vlPixel) (VL_PIXEL_MAXVAL * lightness + 0.5f);
}
}
return (0); /* success */
}
#endif
/* 2D RGB image convolution */
static int
_vlRGBconvolution (CvlImage *src, CvlMask *mask, CvlWindow *window, CvlImage *dest)
{
int x, y, r, c, r1, r2, c1, c2, row, col;
int index, d_index, k_index;
int width, height, k_width, k_height, k_width2, k_height2;
float *kernel, sum_r, sum_g, sum_b;
vlPixel *new_data, *data;
width = src->width;
height = src->height;
/* verify window coords */
if ((window->width > width) ||
(window->width < 0) ||
(window->height > height) ||
(window->height < 0) ||
(window->x > width) ||
(window->x < 0) ||
(window->y > height) ||
(window->y < 0)) {
MessageBox(NULL,"illegal window coordinates\n", "warnning", MB_OK);
return (-1); /* failure */
}
/* duplicate the old image so that the borders are correct */
src->vlImageCopy (src, dest);
r1 = window->y + (mask->height / 2);
r2 = window->height - (mask->height / 2);
c1 = window->x + (mask->width / 2);
c2 = window->width - (mask->width / 2);
data = src->pixel;
new_data = dest->pixel;
kernel = mask->kernel;
k_width = mask->width;
k_height = mask->height;
k_width2 = k_width / 2;
k_height2 = k_height / 2;
for (r=r1; r<r2; r++) {
for (c=c1; c<c2; c++) {
sum_r = sum_g = sum_b = 0;
for (y=0; y<k_height; y++) {
int yk = y*k_width;
int ck2 = c + k_width2;
row = r - y + k_height2;
for (x=0; x<k_width; x++) {
k_index = yk + x;
/* compute data indexes */
col = ck2 - x;
d_index = (row*width + col) * VL_RGB_PIXEL;
sum_r += data[d_index] * kernel[k_index];
sum_g += data[d_index++] * kernel[k_index];
sum_b += data[d_index++] * kernel[k_index];
}
}
index = (r*width + c) * VL_RGB_PIXEL; /* current pixel */
new_data[index] = (vlPixel) sum_r;
new_data[index++] = (vlPixel) sum_g;
new_data[index++] = (vlPixel) sum_b;
}
}
return (0); /* success */
}
int CvlImageProc::vlConvolve (CvlImage *src, CvlMask *mask, CvlWindow *window, CvlImage *dest)
{
/* verify parameters */
if ((!src) || (!mask) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning", MB_OK);
return (-1); /* failure */
}
switch(src->format){
case RGB:
return (_vlRGBconvolution(src, mask, window, dest));
break;
default:
MessageBox(NULL, "convolution format not implemented yet\n", "warnning", MB_OK);
return (-1); /* failure */
break;
}
return (0); /* success */
}
//added new functions
/*************************************************************************
*
* Function Name:
* vlLinertrans()
*
* Paremetres:
* CvlImage *src - pointer to src GRAY image
* CvlWindow *window - compute area(a rectangle)
* CvlImage *dest - pointer to dest GRAY image(it can be src GRAY image)
*
* return:
* int - sucess 0,else -1.
*
* Remarks:
* This function is used for liner gray elongation, it can enhance contrast.
*
************************************************************************/
int CvlImageProc::vlLinertrans(CvlImage *src, CvlWindow *window, CvlImage *dest)
{
int i, j;
int index, width;
int x1, x2, y1, y2;
vlPixel *input;
vlPixel *output;
/* verify parameters */
if ((!src) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != GRAY) {
MessageBox(NULL,"src image is not GRAY\n","warnning",MB_OK);
return (-1); /* failure */
}
/* temp variables to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
input = src->pixel;
output = dest->pixel;
/* proceed to conversion */
for (j=y1; j<y2; j++)
{
for (i=x1; i<x2; i++)
{
index = VL_GRAY_PIXEL * (j*width + i);
if(input[index]<64)
output[index]=0;
else if(input[index]>191)
output[index]=255;
else
output[index]=(input[index]-64)*2;
}
}
return (0); /* success */
}
/*************************************************************************
*
* Function Name:
* vlThreshold()
*
* Paremetres:
* CvlImage *src - pointer to src GRAY image
* CvlWindow *window - compute area(a rectangle)
* CvlImage *dest - pointer to dest GRAY image(it can be src GRAY image)
*
* return:
* int - sucess 0,else -1.
*
* Remarks:
* This function is used for deviding up a GRAY image by an optimized threshold.
*
************************************************************************/
int CvlImageProc::vlThreshold (CvlImage *src, CvlWindow *window, CvlImage *dest)
{
int i, j;
int index, width;
int x1, x2, y1, y2;
vlPixel *input;
vlPixel *output;
long lHistogram[256];//histogram array
unsigned char iThreshold,iNewThreshold,iMaxGrayValue,iMinGrayValue,iMean1GrayValue,iMean2GrayValue;
long lP1,lP2,lS1,lS2;//temp variables
int iIterationTimes;//iteration times
unsigned char pixel;//pixel value of point
/* verify parameters */
if ((!src) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != GRAY) {
MessageBox(NULL,"src image is not GRAY\n","warnning",MB_OK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -