001:
002:
003:
004:
005:
006: #include "binalize.h"
007:
008:
009:
010: LPBYTE GetBin(int bwopt,int bkgopt)
011: {
012: LPBYTE iBin;
013: switch(bwopt){
014: case BW_NORMAL: iBin = GetGray(); break;
015: case BW_COLR: iBin = GetColor(iRED); break;
016: case BW_COLG: iBin = GetColor(iGREEN); break;
017: case BW_COLB: iBin = GetColor(iBLUE); break;
018: default: iBin = GetGray(); break;
019: }
020: GrayToBin(iBin,bkgopt);
021: return iBin;
022: }
023:
024:
025:
026: LPBYTE GetNCol(int col_n,int bwopt,int bkgopt)
027: {
028: LPBYTE iNcol;
029: switch(bwopt){
030: case BW_NORMAL: iNcol = GetGray(); break;
031: case BW_COLR: iNcol = GetColor(iRED); break;
032: case BW_COLG: iNcol = GetColor(iGREEN); break;
033: case BW_COLB: iNcol = GetColor(iBLUE); break;
034: default: iNcol = GetGray(); break;
035: }
036: GrayToNCol(iNcol,col_n,bkgopt);
037: return iNcol;
038: }
039:
040:
041:
042: void Binalize(int bkgopt)
043: {
044: int i,j,thr[50];
045: BYTE gray,iH,iL;
046:
047: toGray();
048:
049: calc_opthmdthr(2,iWHITE+1,iSize,(int*)iGHist,thr);
050:
051: iH = iWHITE; iL = iBLACK;
052: if(bkgopt==BW_BKG_AUTO){
053: int cnt1=0,cnt2=0;
054: for(i=0;i<thr[1];i++) cnt1+=iGHist[i];
055: for(i=thr[1];i<iWHITE;i++) cnt2+=iGHist[i];
056: if(cnt2>cnt1){
057: iH = iBLACK; iL = iWHITE;
058: }
059: }
060:
061: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
062: gray=lpBMP[j*3+i*iLength];
063: if(gray>thr[1]){
064: FillMemory(lpBMP+j*3+i*iLength,3,iH);
065: } else {
066: FillMemory(lpBMP+j*3+i*iLength,3,iL);
067: }
068: }
069: }
070:
071:
072:
073: void ThrBinalize(int thr)
074: {
075: int i,j; BYTE gray;
076:
077: toGray();
078:
079: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
080: gray=lpBMP[j*3+i*iLength];
081: if(gray>thr){
082: FillMemory(lpBMP+j*3+i*iLength,3,iWHITE);
083: } else {
084: FillMemory(lpBMP+j*3+i*iLength,3,iBLACK);
085: }
086: }
087: }
088:
089:
090:
091: void GrayToBin(LPBYTE inBuf,int bkgopt)
092: {
093: BYTE r,g,b,gray;
094: BYTE iH,iL;
095: int i,j,hist[512],thr[50];
096: FillMemory(hist,sizeof(int)*512,0);
097:
098: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
099: hist[inBuf[j+i*iWidth]]++;
100: }
101:
102: calc_opthmdthr(2,iWHITE+1,iSize,hist,thr);
103:
104: iH = iWHITE; iL = iBLACK;
105: if(bkgopt==BW_BKG_AUTO){
106: int cnt1=0,cnt2=0;
107: for(i=0;i<thr[1];i++) cnt1+=hist[i];
108: for(i=thr[1];i<iWHITE;i++) cnt2+=hist[i];
109: if(cnt2>cnt1){
110: iH = iBLACK; iL = iWHITE;
111: }
112: }
113:
114: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
115: gray=inBuf[j+i*iWidth];
116: if(gray>thr[1]){
117: inBuf[j+i*iWidth] = iH;
118: } else {
119: inBuf[j+i*iWidth] = iL;
120: }
121: }
122: }
123:
124:
125:
126: void toNCol(int col_n,int bkgopt)
127: {
128: BYTE r,g,b,gray,colmap[50];
129: int i,j,ii,thr[50];
130:
131: toGray();
132:
133: calc_opthmdthr(col_n,iWHITE+1,iSize,(int*)iGHist,thr);
134:
135: for(i=0;i<col_n;i++){
136: colmap[i] = i*iWHITE/(col_n-1);
137: }
138: if(bkgopt==BW_BKG_AUTO){
139: int hcnt[50],hmax=0,maxi=0;
140: FillMemory(hcnt,sizeof(int)*50,0);
141: for(i=1;i<=col_n;i++){
142: for(ii=thr[i-1];ii<thr[i];ii++)
143: hcnt[i-1]+=iGHist[ii];
144: }
145: for(i=0;i<col_n;i++){
146: if(hcnt[i]>hmax){
147: maxi = i; hmax = hcnt[i];
148: }
149: }
150: if(maxi!=0){
151: BYTE c = colmap[0];
152: for(i=0;i<maxi;i++) colmap[i] = colmap[i+1];
153: colmap[maxi] = c;
154: }
155: }
156:
157: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
158: gray=lpBMP[j*3+i*iLength];
159: for(ii=col_n-1;ii>=0;ii--){
160: if(gray>=thr[ii]){
161: FillMemory(lpBMP+j*3+i*iLength,3,colmap[ii]);
162: break;
163: }
164: }
165: }
166: }
167:
168:
169:
170: void GrayToNCol(LPBYTE inBuf,int col_n,int bkgopt=BW_BKG_NORMAL)
171: {
172: BYTE gray,colmap[50];
173: int i,j,ii,thr[50];
174:
175: calc_opthmdthr(col_n,iWHITE+1,iSize,(int*)iGHist,thr);
176:
177: for(i=0;i<col_n;i++){
178: colmap[i] = i*iWHITE/(col_n-1);
179: }
180: if(bkgopt==BW_BKG_AUTO){
181: int hcnt[50],hmax=0,maxi=0;
182: FillMemory(hcnt,sizeof(int)*50,0);
183: for(i=1;i<=col_n;i++){
184: for(ii=thr[i-1];ii<thr[i];ii++)
185: hcnt[i-1]+=iGHist[ii];
186: }
187: for(i=0;i<col_n;i++){
188: if(hcnt[i]>hmax){
189: maxi = i; hmax = hcnt[i];
190: }
191: }
192: if(maxi!=0){
193: BYTE c = colmap[0];
194: for(i=0;i<maxi;i++) colmap[i] = colmap[i+1];
195: colmap[maxi] = c;
196: }
197: }
198:
199: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
200: gray=inBuf[j+i*iWidth];
201: for(ii=col_n-1;ii>=0;ii--){
202: if(gray>=thr[ii]){
203: inBuf[j+i*iWidth] = colmap[ii];
204: break;
205: }
206: }
207: }
208: }
209:
210:
211:
212:
213: void bwExpand(LPBYTE inBuf,int opt,int repetition)
214: {
215: int px_count;
216: int p_x,p_y;
217: BYTE iFIND,iFILL;
218: LPBYTE tempBuf;
219: int i,ii,x,y,m,n;
220: if(opt==BW_EROSION) {
221: iFIND = iWHITE; iFILL = iBLACK;
222: } else {
223: iFIND = iBLACK; iFILL = iWHITE;
224: }
225:
226: tempBuf=(LPBYTE)GlobalAlloc(GPTR,iSize);
227: CopyMemory(tempBuf,inBuf,iSize);
228: for(i=0;i<repetition;i++){
229: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
230: if(inBuf[x+y*iWidth] == iFIND){
231: px_count = 0;
232: for(ii=0;ii<8;ii++){
233: p_x=x+offset8[i].x; p_y=y+offset8[i].y;
234: if(p_x>0 && p_x<iWidth && p_y>0 && p_y<iHeight){
235: if(inBuf[p_x+p_y*iWidth]==iFILL)
236: px_count ++;
237: }
238: }
239: if(px_count) tempBuf[x+y*iWidth] = iFILL;
240: }
241: }
242: CopyMemory(inBuf,tempBuf,iSize);
243: }
244: GlobalFree(tempBuf);
245: }
246:
247:
248:
249: void bw_thinning(LPBYTE inBuf)
250: {
251: int ia[9],ic[9],i,ix,iy,px,py,m,ir,iv,iw;
252: int iWH=255,iBW=0,iGRAY=100;
253: LPBYTE tempBuf;
254:
255: tempBuf=(LPBYTE)GlobalAlloc(GPTR,iHeight*iLength);
256: CopyMemory(tempBuf,inBuf,iSize);
257:
258: m=iGRAY; ir=1;
259: while(ir!=0){
260: ir=0;
261: for(iy=1;iy<iHeight-1;iy++) for(ix=1;ix<iWidth-1;ix++){
262: if(tempBuf[ix+iy*iWidth]!=iWH) continue;
263: for(i=0;i<8;i++){
264: px = ix+offset8[i].x;
265: py = iy+offset8[i].y;
266: ia[i] = tempBuf[px+py*iWidth];
267: }
268: for(i=0;i<8;i++){
269: if(ia[i]==m){
270: ia[i] = iWH; ic[i] = 0;
271: } else {
272: if(ia[i]<iWH) ia[i]=0;
273: ic[i] = ia[i];
274: }
275: }
276: ia[8] = ia[0]; ic[8] = ic[0];
277: if(ia[0]+ia[2]+ia[4]+ia[6] == iWH*4) continue;
278: for(i=0,iv=0,iw=0;i<8;i++){
279: if(ia[i]==iWH) iv++;
280: if(ic[i]==iWH) iw++;
281: }
282: if(iv<=1) continue;
283: if(iw==1) continue;
284: if(func_cconc(ia)!=1) continue;
285: if(tempBuf[ix+(iy-1)*iWidth]==m){
286: ia[2] = 0;
287: if(func_cconc(ia)!=1) continue;
288: ia[2] = iWH;
289: }
290: if(tempBuf[(ix-1)+iy*iWidth]==m){
291: ia[4] = 0;
292: if(func_cconc(ia)!=1) continue;
293: ia[4] = iWH;
294: }
295: tempBuf[ix+iy*iWidth]=m; ir++;
296: }
297: m++;
298: }
299: for(iy=1;iy<iHeight-1;iy++) for(ix=1;ix<iWidth-1;ix++){
300: if(tempBuf[ix+iy*iWidth]<iWH)
301: tempBuf[ix+iy*iWidth] = iBW;
302: }
303:
304: CopyMemory(inBuf,tempBuf,iSize);
305: GlobalFree(tempBuf);
306: }
307:
308:
309:
310: int func_cconc(int *inb)
311: {
312: int i,icn=0,iWH=255,iBL=0;
313: for(i=0;i<8;i+=2)
314: if(inb[i]==iBL && (inb[i+1]==iWH || inb[i+2]==iWH))
315: icn++;
316: return(icn);
317: }