📄 bar.1_0.cpp
字号:
/*
MODIFICATIONS:
AUGUST 30TH, 2005
-----------------
- Additional conditions added in functions DirConsolidation0() and DirConsolidation1().
- A forth level for function DctBorders()'s output to distinct cross-point between
horizontal and vertical borders.
AUGUST 22TH, 2005
-----------------
- function HfCorrection() added to distinguish more pix to be isolated
*/
#include "MnrFilters.h"
#include "bar.1_0.h"
//===============================================================
// DESCRIPTION : Generate a mask of DCT block borders. Horizontal
// borders are marked with a value of 255, Vertical
// borders are marked with a value of 128 and zones
// that don't belong to borders are 0.
//===============================================================
void DctBorders(Cimg &im, int brows, int bcols, int oy, int ox)
{
int nr = im.getRows();
int nc = im.getCols();
int hs = ox;
int vs = oy;
/*-----------------------------------------------------*/
/* Identify valid offsets: (a)not any borders; (b)only */
/* vertical borders; (c)only horizontal borders */
/*-----------------------------------------------------*/
if ( (oy==brows)&&(ox==bcols) ){
hs = nc;
vs = nr;
}
else if ( (oy==brows)&&(ox!=bcols) )
vs = 0;
else if ( (oy!=brows)&&(ox==bcols) )
hs = 0;
else;
/*--------------------*/
/* Horizontal borders */
/*--------------------*/
for (int y=vs; y<nr; y+=brows)
for (int x=0; x<nc; x++){
im.mBitmap[y][x] = 255;
if ( (y-1)>0 )
im.mBitmap[y-1][x] = 255;
}
/*------------------*/
/* Vertical borders */
/*------------------*/
for (int x=hs; x<nc; x+=bcols)
for (int y=0; y<nr; y++){
#if 0
im.mBitmap[y][x+0] = 128;
if ( (x-1)>0 )
im.mBitmap[y][x-1] = 128;
#else
if ( im.mBitmap[y][x]==255 ){
im.mBitmap[y][x] = 64;
if ( (x-1)>0 && im.mBitmap[y][x-1]==255 )
im.mBitmap[y][x-1] = 64;
}
else{
im.mBitmap[y][x+0] = 128;
if ( (x-1)>0 )
im.mBitmap[y][x-1] = 128;
}
#endif
}
//im.show("mask_DCT1");
}
//=================================================================
// DESCRIPTION : Construct a map that indicates filtering direction
//=================================================================
int DirDecision(Tfixed *sbv, int *sbi, int inf, int sup)
{
int nd = sup+1; // not defined
int ret;
// BACKUP INPUT VECTORS
Tfixed *s;
s = new Tfixed[sup+1];
int *i;
i = new int[sup+1];
for (int k=inf; k<=sup; k++){
s[k] = sbv[k] ;
i[k] = sbi[k];
}
// SORT VALUES
QuickSort(s,i,inf,sup);
// DECISION
if (s[3]<=16)
ret = nd;
else if ( (s[1]-s[0])<1)
ret = nd;
else
ret = i[0];
delete [] s;
delete [] i;
return ret;
}
//==================================================
// DESCRIPTION : Consolidation for the direction map
//==================================================
Err DirConsolidation0(Cimg &din, int h, int w, int nd, int thr)
{
Err err;
int nr = din.getRows();
int nc = din.getCols();
int dw = (w-1)/2;
int dh = (h-1)/2;
Tfixed *nb, *fq;
nb = new Tfixed[nd];
fq = new Tfixed[nd];
int *id;
id = new int[nd];
Cimg dtemp;
err=dtemp=din;
for (int y=dh; y<(nr-dh); y++)
for (int x=dw; x<(nc-dw); x++){
// REINITIALIZE COUNTERS
for (int i=0; i<nd; i++){
nb[i] = 0;
id[i] = i;
}
// COUNT IN THE WINDOW
for (int l=-dh; l<=dh; l++)
for (int c=-dw; c<=dw; c++){
int i = int(dtemp.mBitmap[y+l][x+c]);
if (i>=0 && i<nd){
nb[i]++;
fq[i]++;
}
}
// SORT
QuickSort(nb,id,0,nd-1);
// DECISION BASED ON A MAJORITY VOTE
if ( fq[din.mBitmap[y][x]]>=3 );
else if (nb[nd-1]>=thr){
if ( id[nd-1]==(nd-1) );
else
din.mBitmap[y][x] = id[nd-1];
}
else
din.mBitmap[y][x] = nd-1; // incompatible direction
}
delete [] nb;
delete [] fq;
delete [] id;
return err;
}
//==================================================
// DESCRIPTION : Consolidation for the direction map
//==================================================
Err DirConsolidation1(Cimg &din, int h, int w, int nd, int thr)
{
int nr = din.getRows();
int nc = din.getCols();
int dw = (w-1)/2;
int dh = (h-1)/2;
// Tfixed nb[nd], fq[nd];
// int id[nd];
Tfixed *nb, *fq;
nb = new Tfixed[nd];
fq = new Tfixed[nd];
int *id;
id = new int[nd];
Err err;
Cimg dtemp;
err=dtemp=din;
for (int y=dh; y<(nr-dh); y++)
for (int x=dw; x<(nc-dw); x++){
// reinitialize counters
for (int i=0; i<nd; i++){
nb[i] = 0;
id[i] = i;
}
// count in the window
for (int l=-dh; l<=dh; l++)
for (int c=-dw; c<=dw; c++){
int i = int(dtemp.mBitmap[y+l][x+c]);
if (i>=0 && i<nd){
nb[i]++;
fq[i]++;
}
}
// sort
QuickSort(nb,id,0,nd-1);
// Decision based on a majority vote
if ( fq[din.mBitmap[y][x]]>=3 );
else if (nb[nd-1]>=thr)
din.mBitmap[y][x] = id[nd-1];
else;
}
delete [] nb;
delete [] fq;
delete [] id;
return err;
}
//====================================================================================
// DESCRIPTION : Detect other forbidden zones based on direction detected in a window
//====================================================================================
Err HfCorrection(Cimg &dirmap, int wh, int ww, int thr, Cimg &hfmap)
{
long nr = hfmap.getRows();
long nc = hfmap.getCols();
long dw = (ww-1)/2;
long dh = (wh-1)/2;
Tfixed frq[5];
int nb;
for (long y=dh; y<(nr-dh); y++) {
for (long x=dw; x<(nc-dw); x++) {
nb = 0;
// reinitialize counters
for (int i=0; i<5; i++)
frq[i] = 0;
// count in the window
for (int r=-dh; r<=dh; r++)
for (int c=-dw; c<=dw; c++){
int i = int(dirmap.mBitmap[y+r][x+c]);
frq[i]++;
}
// count the number of directions that have a frequency >= 2
for (int j=0; j<5; j++)
if (frq[j]>=2) nb++;
if (nb>=thr)
hfmap.mBitmap[y][x] = 255;
}
}
return kerr_ok;
}
//====================================================================================
// DESCRIPTION : Identification of different zones and, for the edges, their direction
//====================================================================================
Err BlockReducerLuma(Cimg &in, int brows, int bcols, int boffy, int boffx, Cimg &out, Cimg &hfIsolMap)
{
int x,y;
int nr = in.getRows();
int nc = in.getCols();
Cimg in8bit, imhp, binhf, img;
Err err;
// IDENTIFICATION OF EXTREME HIGH FREQUENCY ZONES
int thr=64*16;
err = Quantification(in,10,8,in8bit,1); IER; // Rounding
err = do2DHpFilter(in8bit,imhp,1/*abs*/,1/*factor*/,"r"); IER; // gain of 16
err = Threshold2(imhp,thr,1,255,binhf);IER;
// MEAN ON HF IMAGE TO DETECT FLAT REGIONS
int thr0 = 2*16;
Cimg imhpm,flatim;
err = do2DLowPassMean(imhp,imhpm,64/*factor*/,"r");IER;
err = Threshold2(imhpm,thr0,0/*inv_mode*/,255,flatim); IER;
err = hfIsolMap = flatim; IER;// Map for output
// BLOCK BORDER MASK GENERATION
Cimg borderMask;
err = borderMask = in;IER;
borderMask.setValues(0);
DctBorders(borderMask,brows,bcols,boffy,boffx);
// CORRECTION FILTERS
Cimg lp0,lp1,lp2,lp3,lpf;
err=do1DLpFilter(in,1,lp0,4,"r");
err=do1DLpFilter(in,3,lp1,4,"r");
err=do1DLpFilter(in,2,lp2,4,"r");
err=do1DLpFilter(in,4,lp3,4,"r");
err=do2DLowPassMean(in,lpf,64/*factor*/,"r");IER;
// DIRECTIONAL HP
Cimg hpd0,hpd1,hpd2,hpd3;
err=do1DHpFilter(in8bit,1,hpd0); // Filtering and Absolute
err=do1DHpFilter(in8bit,3,hpd1);
err=do1DHpFilter(in8bit,2,hpd2);
err=do1DHpFilter(in8bit,4,hpd3);
// ROUND AND TRUNCATE
Truncate(hpd0,8);
Truncate(hpd1,8);
Truncate(hpd2,8);
Truncate(hpd3,8);
// DETECTION/DECISION ON DIRECTIONS
Tfixed s[4];
int i[4];
Cimg dirEdge;
err=dirEdge=in; IER;
dirEdge.setValues(0);
for (y=0; y<nr; y++)
{
for (x=0; x<nc; x++)
{
// ...initialization
s[0] = hpd0.mBitmap[y][x]; i[0] = 0;// direction 090
s[1] = hpd1.mBitmap[y][x]; i[1] = 1;// direction 135
s[2] = hpd2.mBitmap[y][x]; i[2] = 2;// direction 180
s[3] = hpd3.mBitmap[y][x]; i[3] = 3;// direction 045
// ...decision on the direction of the pixel
dirEdge.mBitmap[y][x] = DirDecision( s,i,0,3 );
}
}
// 1st CONSOLIDATION OF THE ISOLATION MAP
Cimg hfcons0, hfcons1;
err = doConsolidationAddRemove1(binhf,1,1,2,3,hfcons0);IER;
// CORRECTION ON THE ISOLATION MAP
err = HfCorrection(dirEdge, 3, 3, 3/*thr*/, hfcons0);IER;
// 2nd CONSOLIDATION OF THE ISOLATION MAP
err = doConsolidationAddRemove1(hfcons0,1,1,0,1,hfcons1);IER;
// CONSOLIDATION OF THE DIRECTION MAP
err= DirConsolidation0(dirEdge,3,3,5/*nb of dir*/,4/*thr*/);IER;
err= DirConsolidation1(dirEdge,3,3,5/*nb of dir*/,4/*thr*/);IER;
// BLOCK BORDER CORRECTION
Cimg ret;
err=ret=in; IER;
ret.setValues(0);
for ( y=0; y<nr; y++)
{
for (x=0; x<nc; x++)
{
if (hfcons1.mBitmap[y][x]!=0)
ret.mBitmap[y][x] = in.mBitmap[y][x];
else if (borderMask.mBitmap[y][x]==0)
ret.mBitmap[y][x] = in.mBitmap[y][x];
else if (borderMask.mBitmap[y][x]==64 || borderMask.mBitmap[y][x]==128)//Vertical
{
if (dirEdge.mBitmap[y][x]==2)
ret.mBitmap[y][x] = in.mBitmap[y][x];
else if (dirEdge.mBitmap[y][x]==1)
ret.mBitmap[y][x] = lp1.mBitmap[y][x];
else if (dirEdge.mBitmap[y][x]==3)
ret.mBitmap[y][x] = lp3.mBitmap[y][x];
else
ret.mBitmap[y][x] = lp0.mBitmap[y][x];
}
else //Horizontal
{
if (dirEdge.mBitmap[y][x]==0)
ret.mBitmap[y][x] = in.mBitmap[y][x];
else if (dirEdge.mBitmap[y][x]==1)
ret.mBitmap[y][x] = lp1.mBitmap[y][x];
else if (dirEdge.mBitmap[y][x]==3)
ret.mBitmap[y][x] = lp3.mBitmap[y][x];
else
ret.mBitmap[y][x] = lp2.mBitmap[y][x];
}
}
}
err=out=ret;
return err;
}
//====================================================================================
// DESCRIPTION :
//====================================================================================
Err BlockReducerChroma(Cimg &in, int brows, int bcols, int boffy, int boffx, Cimg &out)
{
int nr = in.getRows();
int nc = in.getCols();
// BLOCK BORDER MASK GENERATION
Err err;
Cimg borderMask;
err=borderMask=in;IER;
borderMask.setValues(0);
DctBorders(borderMask,brows,bcols,boffy,boffx);
// CORRECTION FILTERS
Cimg lphor,lpver;
err=do1DLpFilter(in,1,lphor,4,"r");IER;
err=do1DLpFilter(in,2,lpver,4,"r");IER;
// BLOCK CORRECTION
Cimg ret;
err=ret=in;
IER;
ret.setValues(0);
for (int y=0; y<nr; y++)
for (int x=0; x<nc; x++){
if (borderMask.mBitmap[y][x]==0)
ret.mBitmap[y][x] = in.mBitmap[y][x];
else if (borderMask.mBitmap[y][x]==128 || borderMask.mBitmap[y][x]==64)
ret.mBitmap[y][x] = lphor.mBitmap[y][x];
else
ret.mBitmap[y][x] = lpver.mBitmap[y][x];
}
err=out=ret;
return err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -