root/lang/cpluspluscli/OpenCvSharp/trunk/OpenCvSharp/Extras.cpp @ 20977

Revision 20977, 4.4 kB (checked in by schima, 2 years ago)

cvGrabFrame -> GrabFrame?

Line 
1/**
2 * (C) 2008 Schima
3 * This code is licenced under the LGPL.
4 */
5
6#include "StdAfx.h"
7#include "Extras.h"
8
9using namespace System;
10using namespace System::Runtime::InteropServices;
11namespace N = KwsmLab::OpenCvSharp;
12
13namespace KwsmLab {
14namespace OpenCvSharp
15{
16        /// <summary>
17        /// Niblackの手法による二値化処理を行う。
18        /// </summary>
19        /// <param name="src">入力画像</param>
20        /// <param name="dst">出力画像</param>
21        /// <param name="size">局所領域のサイズ</param>
22        /// <param name="k">係数</param>
23        void Extras::BinarizeNiblack(N::IplImage^ src, N::IplImage^ dst, Int32 size, Double k) 
24        {
25                CHECK_NULL(src);
26                CHECK_NULL(dst);
27                // グレースケールのみ
28                if(src->NChannels != 1){
29                        throw gcnew ArgumentException("入力画像はグレースケール画像でなければなりません。");
30                }
31                if(dst->NChannels != 1){
32                        throw gcnew ArgumentException("出力画像はグレースケール画像でなければなりません。");
33                }
34                // サイズのチェック
35                if(size >= 3 == 0){
36                        throw gcnew ArgumentException("局所領域のサイズは3以上でなければなりません。");
37                }
38                if(size % 2 == 0){
39                        throw gcnew ArgumentException("局所領域のサイズは奇数でなければなりません。");
40                }
41
42                N::IplImage^ gray = src->Clone();
43                gray->EqualizeHist();
44
45                Byte* p = dst->ImageDataPtr;
46                double m, s;
47
48                for (int y = 0; y < gray->Height; y++) {
49                        for (int x = 0; x < gray->Width; x++) {
50                                MeanStddev(gray, x, y, size, &m, &s);
51                                int offset = (dst->WidthStep * y) + x;
52                                p[offset] = (Byte)(m + k*s);
53                        }
54        }
55        }
56
57        /// <summary>
58        /// Sauvolaの手法による二値化処理を行う。
59        /// </summary>
60        /// <param name="src">入力画像</param>
61        /// <param name="dst">出力画像</param>
62        /// <param name="size">局所領域のサイズ</param>
63        /// <param name="k">係数</param>
64        /// <param name="r">係数</param>
65        void Extras::BinarizeSauvola(N::IplImage^ src, N::IplImage^ dst, Int32 size, Double k, Double r)
66        {
67                CHECK_NULL(src);
68                CHECK_NULL(dst);
69                // グレースケールのみ
70                if(src->NChannels != 1){
71                        throw gcnew ArgumentException("入力画像はグレースケール画像でなければなりません。");
72                }
73                if(dst->NChannels != 1){
74                        throw gcnew ArgumentException("出力画像はグレースケール画像でなければなりません。");
75                }
76                if(src->Width != dst->Width || src->Height != dst->Height){
77                        throw gcnew ArgumentException("入力画像と出力画像のサイズが違います。");
78                }
79                // サイズのチェック
80                if(size >= 3 == 0){
81                        throw gcnew ArgumentException("局所領域のサイズは3以上でなければなりません。");
82                }
83                if(size % 2 == 0){
84                        throw gcnew ArgumentException("局所領域のサイズは奇数でなければなりません。");
85                }
86
87                N::IplImage^ gray = src->Clone();
88                gray->EqualizeHist();
89
90                Byte* p = dst->ImageDataPtr;
91                double m, s;
92                int offset;
93
94                for (int y = 0; y < gray->Height; y++) {
95                        for (int x = 0; x < gray->Width; x++) {
96                                MeanStddev(gray, x, y, size, &m, &s);
97                                offset = (dst->WidthStep * y) + x;
98                                p[offset] = (Byte)(m + (1 + k*(s/r - 1)));
99                        }
100        }
101        }
102
103        /// <summary>
104        /// 注目画素の周辺画素の平均値と標準偏差を求める
105        /// </summary>
106        /// <param name="img">画像の画素データ</param>
107        /// <param name="x">x座標</param>
108        /// <param name="y">y座標</param>
109        /// <param name="size">周辺画素の探索サイズ。奇数でなければならない</param>
110        /// <param name="mean">出力される平均</param>
111        /// <param name="stddev">出力される標準偏差</param>
112        void Extras::MeanStddev(N::IplImage^ img, Int32 x, Int32 y, Int32 size, Double* mean, Double* stddev)
113        {
114                int count = 0;
115                int sum = 0;
116                int sum2 = 0;
117                Byte* p = img->ImageDataPtr;
118                int xxx, yyy;
119                int size2 = size / 2;
120                int widthStep = img->Width;
121                Byte v;
122
123                for(int xx = 0; xx<size; xx++){
124                        for(int yy = 0; yy<size; yy++){
125                                xxx = x + xx - size2;
126                                yyy = y + yy - size2;
127                                if(xxx < 0 || xxx >= img->Width || yyy < 0 || yyy >= img->Height){
128                                        continue;
129                                }
130                                v = p[widthStep * yyy + xxx];
131                                sum += v;
132                                sum2 += v * v;
133                                count++;
134                        }
135                }
136                *mean = (double)sum / count;
137                double var = (double)sum2 / count - (*mean)*(*mean);
138                if(var < 0.0) var = 0.0;
139                *stddev = sqrt(var);
140        }
141
142}
143}
Note: See TracBrowser for help on using the browser.