00001 #include <stdlib.h>
00002 #include "NuppelVideoPlayer.h"
00003 extern "C" {
00004 #include "avcodec.h"
00005 }
00006 #include "frame.h"
00007
00008 #include "FrameAnalyzer.h"
00009 #include "EdgeDetector.h"
00010
00011 namespace edgeDetector {
00012
00013 using namespace frameAnalyzer;
00014
00015 unsigned int *
00016 sgm_init_exclude(unsigned int *sgm, const AVPicture *src, int srcheight,
00017 int excluderow, int excludecol, int excludewidth, int excludeheight)
00018 {
00019
00020
00021
00022
00023
00024
00025
00026 const int srcwidth = src->linesize[0];
00027 int rr, cc, dx, dy, rr2, cc2;
00028 unsigned char *rr0, *rr1;
00029
00030 memset(sgm, 0, srcwidth * srcheight * sizeof(*sgm));
00031 rr2 = srcheight - 1;
00032 cc2 = srcwidth - 1;
00033 for (rr = 0; rr < rr2; rr++)
00034 {
00035 for (cc = 0; cc < cc2; cc++)
00036 {
00037 if (!rrccinrect(rr, cc, excluderow, excludecol,
00038 excludewidth, excludeheight))
00039 {
00040 rr0 = &src->data[0][rr * srcwidth + cc];
00041 rr1 = &src->data[0][(rr + 1) * srcwidth + cc];
00042 dx = rr1[1] - rr0[0];
00043 dy = rr1[0] - rr0[1];
00044 sgm[rr * srcwidth + cc] = dx * dx + dy * dy;
00045 }
00046 }
00047 }
00048 return sgm;
00049 }
00050
00051 #ifdef LATER
00052 unsigned int *
00053 sgm_init(unsigned int *sgm, const AVPicture *src, int srcheight)
00054 {
00055 return sgm_init_exclude(sgm, src, srcheight, 0, 0, 0, 0);
00056 }
00057 #endif
00058
00059 int
00060 sort_ascending(const void *aa, const void *bb)
00061 {
00062 return *(unsigned int*)aa - *(unsigned int*)bb;
00063 }
00064
00065 int
00066 edge_mark(AVPicture *dst, int dstheight,
00067 int extratop, int extraright, int extrabottom, int extraleft,
00068 const unsigned int *sgm, unsigned int *sgmsorted, int percentile,
00069 int excluderow, int excludecol, int excludewidth, int excludeheight)
00070 {
00071
00072
00073
00074
00075
00076
00077
00078
00079 static const int MINTHRESHOLDPCT = 95;
00080
00081 const int dstwidth = dst->linesize[0];
00082 const int padded_width = extraleft + dstwidth + extraright;
00083 unsigned int thresholdval;
00084 int nn, dstnn, ii, rr, cc, first, last, last2;
00085
00086 (void)extrabottom;
00087
00088
00089
00090
00091
00092
00093
00094 nn = 0;
00095 for (rr = 0; rr < dstheight; rr++)
00096 {
00097 for (cc = 0; cc < dstwidth; cc++)
00098 {
00099 if (!rrccinrect(rr, cc, excluderow, excludecol,
00100 excludewidth, excludeheight))
00101 {
00102 sgmsorted[nn++] = sgm[(extratop + rr) * padded_width +
00103 extraleft + cc];
00104 }
00105 }
00106 }
00107
00108 dstnn = dstwidth * dstheight;
00109 #if 0
00110 assert(nn == dstnn -
00111 (min(max(0, excluderow + excludeheight), dstheight) -
00112 min(max(0, excluderow), dstheight)) *
00113 (min(max(0, excludecol + excludewidth), dstwidth) -
00114 min(max(0, excludecol), dstwidth)));
00115 #endif
00116 memset(dst->data[0], 0, dstnn * sizeof(*dst->data[0]));
00117
00118 if (!nn)
00119 {
00120
00121 return 0;
00122 }
00123
00124 qsort(sgmsorted, nn, sizeof(*sgmsorted), sort_ascending);
00125
00126 ii = percentile * nn / 100;
00127 thresholdval = sgmsorted[ii];
00128
00129
00130
00131
00132
00133 for (first = ii; first > 0 && sgmsorted[first] == thresholdval; first--) ;
00134 if (sgmsorted[first] != thresholdval)
00135 first++;
00136 if (first * 100 / nn < MINTHRESHOLDPCT)
00137 {
00138 unsigned int newthresholdval;
00139
00140 last2 = nn - 1;
00141 for (last = ii; last < last2 && sgmsorted[last] == thresholdval;
00142 last++) ;
00143 if (sgmsorted[last] != thresholdval)
00144 last--;
00145
00146 newthresholdval = sgmsorted[min(last + 1, nn - 1)];
00147 if (thresholdval == newthresholdval)
00148 {
00149
00150 return 0;
00151 }
00152
00153 thresholdval = newthresholdval;
00154 }
00155
00156
00157 for (rr = 0; rr < dstheight; rr++)
00158 {
00159 for (cc = 0; cc < dstwidth; cc++)
00160 {
00161 if (!rrccinrect(rr, cc, excluderow, excludecol,
00162 excludewidth, excludeheight) &&
00163 sgm[(extratop + rr) * padded_width + extraleft + cc] >=
00164 thresholdval)
00165 dst->data[0][rr * dstwidth + cc] = UCHAR_MAX;
00166 }
00167 }
00168 return 0;
00169 }
00170
00171 #ifdef LATER
00172 int edge_mark_uniform(AVPicture *dst, int dstheight, int extramargin,
00173 const unsigned int *sgm, unsigned int *sgmsorted,
00174 int percentile)
00175 {
00176 return edge_mark(dst, dstheight,
00177 extramargin, extramargin, extramargin, extramargin,
00178 sgm, sgmsorted, percentile, 0, 0, 0, 0);
00179 }
00180 #endif
00181
00182 int edge_mark_uniform_exclude(AVPicture *dst, int dstheight, int extramargin,
00183 const unsigned int *sgm, unsigned int *sgmsorted, int percentile,
00184 int excluderow, int excludecol, int excludewidth, int excludeheight)
00185 {
00186 return edge_mark(dst, dstheight,
00187 extramargin, extramargin, extramargin, extramargin,
00188 sgm, sgmsorted, percentile,
00189 excluderow, excludecol, excludewidth, excludeheight);
00190 }
00191
00192 };
00193
00194 EdgeDetector::~EdgeDetector(void)
00195 {
00196 }
00197
00198 int
00199 EdgeDetector::setExcludeArea(int row, int col, int width, int height)
00200 {
00201 (void)row;
00202 (void)col;
00203 (void)width;
00204 (void)height;
00205 return 0;
00206 }
00207
00208