public static void Write(this CvMat matrix, XmlElement parent, string elemName)
        {
            XmlElement me = parent.OwnerDocument.CreateElement(elemName);

            me.SetAttribute("cols", matrix.Cols.ToString());
            me.SetAttribute("rows", matrix.Rows.ToString());
            me.SetAttribute("type", matrix.ElemType.ToString());
            StringBuilder sb = new StringBuilder();

            switch (matrix.ElemType)
            {
            case MatrixType.F32C1:
                for (int x = 0; x < matrix.Cols; ++x)
                {
                    for (int y = 0; y < matrix.Rows; ++y)
                    {
                        if (sb.Length > 0)
                        {
                            sb.Append(", ");
                        }
                        sb.Append(matrix.Get2D(x, y).Val0);
                    }
                }
                break;

            case MatrixType.F64C1:
                for (int x = 0; x < matrix.Cols; ++x)
                {
                    for (int y = 0; y < matrix.Rows; ++y)
                    {
                        if (sb.Length > 0)
                        {
                            sb.Append(", ");
                        }
                        sb.Append(matrix.Get2D(x, y).Val0);
                    }
                }
                break;

            default:
                throw new Exception("Write unsupported MatrixType " + matrix.ElemType);
            }
            me.SetAttribute("values", sb.ToString());
        }
示例#2
0
        // => mat = 8bit binary image (0/255)
        // <= return true if of the 9 pixels in the point's area, at least 5 are white?
        public bool checkFeatureArea(CvMat mat, CvPoint2D32f point, int areaSize = 2)
        {
            float countWhites = 0;

            int x0 = (int)point.X - areaSize;

            if (x0 < 0)
            {
                return(false);
            }
            int y0 = (int)point.Y - areaSize;

            if (y0 < 0)
            {
                return(false);
            }
            int x1 = x0 + areaSize * 2;

            if (x1 >= mat.Cols)
            {
                return(false);
            }
            int y1 = y0 + areaSize * 2;

            if (y1 >= mat.Rows)
            {
                return(false);
            }

            for (int j = y0; j <= y1; ++j)
            {
                for (int i = x0; i <= x1; ++i)
                {
                    //Console.WriteLine( "Checking " + i + "," + j + "=" + mat.Get2D( i, j ) );
                    if (mat.Get2D(j, i) != 0)
                    {
                        ++countWhites;
                    }
                }
            }

            // we don't want white dots in black areas, or black dots in white areas
            float area = (x1 - x0 + 1) * (y1 - y0 + 1);

            if (countWhites >= area * 0.4f && countWhites <= area * 0.7f)
            {
                return(true);
            }
            return(false);
        }
示例#3
0
        // NOTE : Also seems not well written and craves optimization at places. P.A.N.A.R.G.O.
        // => frame = 8 bit greyscale CvMat
        static public void ContrastEnhancement(CvMat frame)
        {
            //CvMat originalFrame = frame; // return this if cannot enhance
            //if (frame.ElemType != MatrixType.U8C1)
            //	frame = MatOps.Convert(frame, MatrixType.U8C1, 1 / 255.0 );

            /////original histogram
            const int HistBinSize = 256;

            int[] histSizes = new int[1];
            histSizes[0] = HistBinSize;
            CvHistogram hist = new CvHistogram(histSizes, HistogramFormat.Array);

            Cv.CalcArrHist(frame, hist, false);               // size = 256 implied

            CvHistogram newHist    = MatOps.CopyHistogram(hist);
            CvArr       newHistBin = newHist.Bins;

            //double[] origVals = new double[hist.Bins.GetDims( 0 )];
            List <double> origVals = new List <double>(HistBinSize);

            for (int i = 0; i < HistBinSize; i++)
            {
                double elem = newHistBin.GetReal1D(i);
                if (elem != 0)
                {
                    origVals.Add(elem);
                }
            }

            // FIX : See no need for histL, since we have origVals
            //////histogram with only nonzero bins
            //CvMat histL = new CvMat( imageRows, imageCols, MatrixType.F32C1, new CvScalar( 0 ) );
            //for (i = 0; i < origVals.size(); i++)
            //	histL.at<float>( i, 0 ) = origVals.at( i );

            List <double> peakValues = new List <double>(HistBinSize);             //std::vector<int> peakValues;

            //////////3 bin search window
            for (int i = 1; i < origVals.Count - 2; ++i)
            {
                double elem = origVals[i];
                if (elem > origVals[i - 1] && elem > origVals[i + 1])
                {
                    peakValues.Add(elem);
                }
            }

            if (peakValues.Count == 0)
            {
                //Console.Out.WriteLine( "Cannot enhance" );
                return;                 // cannot enhance?
            }

            //////Upper threshold
            double threshUP = 0;

            for (int i = 0; i < peakValues.Count; ++i)
            {
                threshUP += peakValues[i];
            }
            threshUP /= peakValues.Count;

            //////Lower threshold
            double threshDOWN = Math.Min((frame.Cols * frame.Rows), threshUP * origVals.Count) / 256.0;
            //Console.Out.WriteLine( "Enhance thresholds " + threshUP + "/" + threshDOWN );

            //////histogram reconstruction
            CvArr histBins = hist.Bins;

            for (int i = 0; i < HistBinSize; ++i)
            {
                double histElem = histBins.GetReal1D(i);
                if (histElem > threshUP)
                {
                    histBins.SetReal1D(i, threshUP);
                }
                else if (histElem <= threshUP && histElem >= threshDOWN)
                {
                    continue;
                }
                else if (histElem < threshDOWN && histElem > 0)
                {
                    histBins.SetReal1D(i, threshDOWN);
                }
                else if (histElem == 0)
                {
                    continue;
                }
            }
            // accumulated values(?)
            double[] accVals = new double[HistBinSize];             //std::vector<int> accVals;
            accVals[0] = (histBins.GetReal1D(0));
            for (int i = 1; i < HistBinSize; ++i)
            {
                accVals[i] = (accVals[i - 1] + histBins[i]);
            }

            byte[] lookUpTable = new byte[HistBinSize];             //cv::Mat lookUpTable = cv::Mat::zeros( hist.size(), CV_8UC1 );
            for (int i = 0; i < HistBinSize; ++i)
            {
                lookUpTable[i] = (byte)(255.0 * accVals[i] / accVals[255]);
            }

            // assign computed values to input frame
            //Console.Out.Write( "Enhance-->" );
            for (int i = 0; i < frame.Cols; ++i)
            {
                for (int j = 0; j < frame.Rows; ++j)
                {
                    // there is NO mask, thus no need to check for; was: "if (mask.data)..."
                    byte oldValue = (byte)frame.Get2D(j, i);
                    byte newValue = lookUpTable[oldValue];
                    //if ((newValue <1 || newValue > 254) && (newValue != oldValue)) Console.Out.Write( oldValue + " " + newValue + "|");
                    frame.Set2D(j, i, newValue);
                    //frame.SetReal2D( j, i, lookUpTable[ (int)(255.0 * frame.GetReal2D( j, i )) ] / 255.0);
                }
            }
            //Console.Out.WriteLine();

            //frame = MatOps.Convert( frame, MatrixType.U8C1, 255.0 );
        }
示例#4
0
        // 孤立輝点除去
        // 周囲に輝点が無い場合,その輝点を消す
        static CvMat removeNoize(CvMat image)
        {
            // 1px大きい作業用画像
            CvMat workImage = new CvMat( image.Rows+1, image.Cols+1, MatrixType.U8C1 );
            image.CopyMakeBorder( workImage, new CvPoint(1, 1), BorderType.Constant );

            // 走査
            for ( int row = 0; row < image.Rows; row++ )
            {
                for ( int col = 0; col < image.Cols; col++ )
                {
                    // 注目画素が暗点ならば何もしない
                    if ( 0 == image.Get2D( row, col ))
                        continue;

                    // 範囲3x3の輝点が1ならば,中心画素を暗点にする
                    CvRect rect = new CvRect( col, row, 3, 3 );
                    CvMat area;
                    workImage.GetSubArr ( out area, rect );
                    int nonzero = area.CountNonZero();
                    if ( 1 == nonzero )
                        image.Set2D( row, col, 0 );
                }
            }
            return image;
        }
示例#5
0
        /// <summary>
        /// CCD座標(cx,cy)->(az,alt)に変換
        /// </summary>
        //
        //   CCD座標(cx,cy):CCD中心からの誤差座標[pix]    Std. Cam が基準(cx = x-xc, cy = y-yc)
        //   中心位置(az_c,alt_c)と視野回転(theta_c)
        //   fl:焦点距離[mm], ccdpx,ccdpy:ピクセル間隔[mm]

        public void cxcy2azalt(double cx, double cy,
                               double az_c, double alt_c, int mode, double theta_c,
                               double fl, double ccdpx, double ccdpy,
                               ref double az, ref double alt)
        {
            double rad = Math.PI / 180.0;
            double cxmm, cymm;

            //ターゲットの方向余弦
            if (mode == mmEast)
            {
                cxmm = -cx * ccdpx; // +ccd -az
                cymm = +cy * ccdpy; // +ccd +alt
            }
            else
            {                       //mmWest
                cxmm = +cx * ccdpx; // +ccd +az
                cymm = -cy * ccdpy; // +ccd -alt
            }
            CvMat v1 = new CvMat(3, 1, MatrixType.F64C1);

            v1.Set2D(0, 0, fl);
            v1.Set2D(1, 0, -cxmm);
            v1.Set2D(2, 0, cymm);
            v1.Normalize(v1);// 方向余弦化

            CvMat v2 = new CvMat(3, 1, MatrixType.F64C1);
            CvMat Rx = new CvMat(3, 3, MatrixType.F64C1);
            CvMat Rz = new CvMat(3, 3, MatrixType.F64C1);
            CvMat Ry = new CvMat(3, 3, MatrixType.F64C1);

            //Rx.rotX(-theta_c * rad); // 回転マトリクスをセット
            double sin = Math.Sin(-theta_c * rad);
            double cos = Math.Cos(-theta_c * rad);

            Rx.Set2D(0, 0, 1); Rx.Set2D(0, 1, 0); Rx.Set2D(0, 2, 0);
            Rx.Set2D(1, 0, 0); Rx.Set2D(1, 1, cos); Rx.Set2D(1, 2, -sin);
            Rx.Set2D(2, 0, 0); Rx.Set2D(2, 1, sin); Rx.Set2D(2, 2, cos);


            //Rz.rotZ(-az_c   *rad ); // 天球座標系と回転方向が逆なのでマイナス
            sin = Math.Sin(-az_c * rad);
            cos = Math.Cos(-az_c * rad);
            Rz.Set2D(0, 0, cos); Rz.Set2D(0, 1, -sin); Rz.Set2D(0, 2, 0);
            Rz.Set2D(1, 0, sin); Rz.Set2D(1, 1, cos); Rz.Set2D(1, 2, 0);
            Rz.Set2D(2, 0, 0); Rz.Set2D(2, 1, 0); Rz.Set2D(2, 2, 1);

            //Ry.rotY(-alt_c  *rad ); // 回転マトリクスをセット
            sin = Math.Sin(-alt_c * rad);
            cos = Math.Cos(-alt_c * rad);
            Ry.Set2D(0, 0, cos); Ry.Set2D(0, 1, 0); Ry.Set2D(0, 2, sin);
            Ry.Set2D(1, 0, 0); Ry.Set2D(1, 1, 1); Ry.Set2D(1, 2, 0);
            Ry.Set2D(2, 0, -sin); Ry.Set2D(2, 1, 0); Ry.Set2D(2, 2, cos);
            v2 = Rz * (Ry * (Rx * v1)); // 順番注意(画像中心をx軸に一致させている状態がスタート)

            // Retrun Val
            az = Math.Atan2(-v2.Get2D(1, 0), v2.Get2D(0, 0)) / rad;
            if (az < 0)
            {
                az += 360;
            }
            alt = Math.Asin(v2.Get2D(2, 0)) / rad;

            //    //Az_Cとの距離が近い値を採用
            //    double az2 = az - 360;
            //    double az3 = az + 360;
            //    double dis1 = Math.Abs(az - az_c);
            //    double dis2 = Math.Abs(az2 - az_c);
            //    double dis3 = Math.Abs(az3 - az_c);
            //    if (dis1 > dis2) az = az2;
            //    if (dis1 > dis3) az = az3;
        }