• Home »
  • Cao học »
  • Kỹ thuật sử dụng giá trị trung bình của điểm ảnh và ứng dụng

Kỹ thuật sử dụng giá trị trung bình của điểm ảnh và ứng dụng


Bài này chúng tôi xin giới thiệu Kỹ thuật sử dụng giá trị trung bình điểm ảnh trong việc nhận dạng các đối tượng chuyển động, ứng dụng vào bài toán thực tế là “xây dựng bài toán nhận dạng máy bay huấn luyện”. Bài toán này mục đích để mô phỏng một súng bắn máy bay và một chương trình mô phỏng các loại máy bay bay trên bầu trời. Súng bắn máy bay sẽ được gắn camera vào nòng súng, và khi người sử dụng hướng súng lên để quan sát máy bay. Hệ thống phải đảm bảo camera nhận dạng và xác định vị trí máy bay, để người sử dụng có thể xác nhận có thể thực hiện việc bắn trúng máy bay hay không.

Chương trình được trích từ luận văn cao học, cần tham khảo mã nguồn liên hệ qua [email protected]

1. Ý tưởng thuật toán.

Input: N frame liên tiếp thu được từ camera giảm sát có sự truyển động F1, F2…Fn, mỗi frame có kích thước M x N.
Output: Xác định trên toàn bộ ảnh, kiểm tra điểm ảnh tại vị trí (x,y) có phải điểm ảnh màu đối tượng hay không.
Ta có thể xác định được một đối tượng có dịch chuyển hay không dựa vào sự thay đổi giá trị màu của điểm ảnh đó trong các frame liên tiếp khác nhau. Tuy nhiên nếu chỉ dựa vào sự thay đổi của màu sắc để khẳng định có đối tượng dịch chuyển thì không chính xác. Nguyên nhân là do màu sắc của ảnh chịu ảnh hưởng bởi góc quay của camera, thời tiết, chất lượng hình ảnh của camera. Camera có sự thay đổi, di chuyển điều này làm cho hình ảnh ta thu nhận được có sự dịch chuyển so với hình ảnh trước đó, đây là có thể là dịch chuyển của nền hoặc chuyển động của đối tượng. Tư tưởng của thuật toán là tính độ dịch chuyển của các đối tượng được để tìm ra đối tượng cần xác định cho bài toán. Từ đó, đưa ra được những điểm ảnh mà tại đó có phải màu đối tượng cần xác định hay không.

	Thuật toán
	1)	Begin
        2)	Xác định điểm ảnh là đối tượng Colorlookup


        N-Frame1

	3)	Tính ma trận tần xuất xuất hiện của màu là đối tượng colorProb vào điều kiện màu là 
                màu của đối tượng
         
          N-Frame2

         Với Pi(x,y) giá trị màu của ảnh tại frame thứ Fi. n: là số frame đang xét (với n = 3 ÷ 7).
        4)	Tính ma trận Color(x,y) để lưu lại các vị trí nào điểm ảnh của đối tượng, 
                điểm ảnh nào đối tượng là nền tại điểm ảnh có tọa độ (x,y). 
                Dự trên việc so sánh tần xuất xuất hiện điểm ảnh với ngưỡng k1. 


           N-Frame3


          k1: là giá trị thực nghiệm, tùy vào từng bài toán và đối tượng để xác định ngưỡng K phù hợp.
          Ví dụ: Với số frame xét liên tục là n =5 thì k1 có giá trị là 1/5, 2/5, 3/5, 4/5, 5/5 tương 
          ứng với 0.2, 0.4, 0.6, 0.8 và 1
        5)	Xác định ma trận độ dịch chuyển trung bình DIFFS của màu đối tượng

 
         N-frame4

          Trong đó: DIFFS(x,y) là độ dịch chuyển trung bình của đối tượng tại điểm ảnh có tọa độ (x,y).

         6)	 Xác định ngưỡng đặc trưng nonDiffs cho những điểm ảnh không phải là đối tượng, dựa vào 
                 ma trận Color đã tính ở bước 4. 

          
         N-Frame5

	 Tính độ dịch chuyển của tất cả các điểm ảnh dựa trên ngưỡng đặc trung NonDiffs vừa tính đươc.

          N-Frame6
	
	7)	 Tính độ dịch chuyển của tất cả các điểm ảnh dựa trên ngưỡng đặc trung NonDiffs vừa tính đươc.
Delta_color(x,y) = DIFFS(x,y) - nonDiffs	
        8)	Như vậy điểm ảnh được xác định là đối tượng chuyển động nếu hoản mãn 2 điều kiện: 
	               a)   Có màu sắc giống đối tượng cần quan sát Color(x,y)=1
	               b)    Có độ dịch truyển điểm ảnh khác với các điểm ảnh dựa vào  ngưỡng K2 với công thức:
                             Delta_color(x,y) > k2. 
               Như vậy điểm ảnh là đối tượng khi :

         N-Frame7

        Với Ngưỡng k2 là giá trị thu được từ thực nghiệm.
 End;

2. Code được thể hiên ngôn ngữ lập trình C#

public class NFrame
    {
        // Ma trận lưu cường độ điểm ảnh
        private int[,] I_frame_0;
        private int[,] I_frame_1;
        private int[,] I_frame_2;
        private int[,] I_frame_3;
        private int[,] I_frame_4;
        private int[,] matranMark;

        // Ma trân xác nhận màu của đối tượng, ghi lại xem màu đầu vào có phải là đối tượng không
        private int[,] ColorLookup_frame_0;
        private int[,] ColorLookup_frame_1;
        private int[,] ColorLookup_frame_2;
        private int[,] ColorLookup_frame_3;
        private int[,] ColorLookup_frame_4;

        // Ma trận xác định tần xuất số lần điểu ảnh có màu của đối tượng
        private float[,] ColorProb;

        // Ma trận dùng để lưu lại xem điểm ảnh đó có phải là đối tượng 
        // dựa trên tần xuất điểm ảnh là đối tượng phải lớn hơn ngưỡng.
        private int[,] Color;

        // Ma trận độ lệch trung bình cường độ sáng của điểm ảnh giữa các frame.
        private int[,] DIFFS;

        // Ma trận ghi nhận lại xem điểm ảnh nào là điểm anh chuyển động > ngưỡng K2, điểm ảnh không chuyển động ngược lại
        private int[,] Objectmove;

        public void Run(ref Bitmap pImage, int pFrameIndex, int k1, int k2, float pThresholdK1, float pThreshostK2, int pDelta, int pCanDuoiDt, int pCanTrenDt, PictureBox pDisplayBox)
        {
            Lock_bitmap bm = new Lock_bitmap(pImage);
            List doituongList = new List();

            if (pFrameIndex == 1)
            {
                I_frame_4 = new int[pImage.Width, pImage.Height];
                I_frame_3 = new int[pImage.Width, pImage.Height];
                I_frame_2 = new int[pImage.Width, pImage.Height];
                I_frame_1 = new int[pImage.Width, pImage.Height];
                I_frame_0 = new int[pImage.Width, pImage.Height];

                ColorLookup_frame_4 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_3 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_2 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_1 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_0 = new int[pImage.Width, pImage.Height];

                ColorProb = new float[pImage.Width, pImage.Height];


                //pThresholdK1 = 0.5f;
                Color = new int[pImage.Width, pImage.Height];

                DIFFS = new int[pImage.Width, pImage.Height];

                //Delta_color = new int[pImage.Width, pImage.Height];

                Objectmove = new int[pImage.Width, pImage.Height];
            }
            else
                if (pFrameIndex % pDelta == 0)
                {
                    I_frame_4 = (int[,])I_frame_3.Clone();
                    I_frame_3 = (int[,])I_frame_2.Clone();
                    I_frame_2 = (int[,])I_frame_1.Clone();
                    I_frame_1 = (int[,])I_frame_0.Clone();

                    ColorLookup_frame_4 = (int[,])ColorLookup_frame_3.Clone();
                    ColorLookup_frame_3 = (int[,])ColorLookup_frame_2.Clone();
                    ColorLookup_frame_2 = (int[,])ColorLookup_frame_1.Clone();
                    ColorLookup_frame_1 = (int[,])ColorLookup_frame_0.Clone();


                    bm.LockBitmap();
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            byte red, green, blue;
                            red = bm.GetPixel(i, j).red;
                            green = bm.GetPixel(i, j).green;
                            blue = bm.GetPixel(i, j).blue;

                            // Tra cứu xem màu có phải của đối tượng không.
                            if (ColorLookup(red, green, blue, k1, k2))
                                ColorLookup_frame_0[i, j] = 1;
                            else
                                ColorLookup_frame_0[i, j] = 0;

                            // Tính cường độ sáng tại mỗi điểm ảnh
                            I_frame_0[i, j] = (red + green + blue) / 3;
                        }
                    }

                    bm.UnlockBitmap();

                    // Tính ma trận tần xuất số lần điểm ảnh là đối tượng Colorprob[]
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            ColorProb[i, j] = (float)(ColorLookup_frame_4[i, j] + ColorLookup_frame_3[i, j] +
                                ColorLookup_frame_2[i, j] + ColorLookup_frame_1[i, j] + ColorLookup_frame_0[i, j]) / 5;
                        }
                    }

                    // Tính ma trận xác nhận điểm ảnh nào là đối tượng và lưu trong ma trận Color
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            if (ColorProb[i, j] > pThresholdK1)
                                Color[i, j] = 1;
                            else Color[i, j] = 0;
                        }
                    }

                    // tinh DIFFS
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            DIFFS[i, j] = (Math.Abs(I_frame_0[i, j] - I_frame_1[i, j]) + Math.Abs(I_frame_1[i, j] - I_frame_2[i, j])
                                + Math.Abs(I_frame_2[i, j] - I_frame_3[i, j]) + Math.Abs(I_frame_3[i, j] - I_frame_4[i, j])) / 4;
                        }
                    }

                    //Tinhs nonDiffs
                    float nonDiffs = 0;
                    float SumPointOfnonDiffs = 0;
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            if (Color[i, j] == 0)
                            {
                                nonDiffs += DIFFS[i, j];
                                SumPointOfnonDiffs++;
                            }
                        }
                    }
                    nonDiffs = nonDiffs / SumPointOfnonDiffs;

                    //tinh Object move
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            // xác định điểm ảnh là đối tượng
                            if ((Color[i, j] == 1) && (DIFFS[i, j] - (int)nonDiffs > pThreshostK2))
                                Objectmove[i, j] = 1;
                            else
                                Objectmove[i, j] = 0;
                        }
                    }

                    doituongList = Utility.TimKiemDoiTuongLTNew(Objectmove, bm.Bitmap.Width, bm.Bitmap.Height, pCanDuoiDt, pCanTrenDt);

                }

            if (pFrameIndex > 5 * pDelta)
            {
                bm.LockBitmap();
                Lock_bitmap.PixelData a;
                a.red = 255; a.green = 0; a.blue = 0;

                Lock_bitmap.PixelData kh;
                kh.red = 0; a.green = 0; a.blue = 0;

                int[,] dt = Utility.MaTranDoiTuong(bm.Bitmap.Width, bm.Bitmap.Height, doituongList);

                for (int i = 0; i < bm.Bitmap.Width; i++)
                {
                    for (int j = 0; j < bm.Bitmap.Height; j++)
                    {
                        if (dt[i, j] == 1)
                            bm.SetPixel(i, j, a);
                    }
                }
                bm.UnlockBitmap();
                pDisplayBox.Image = bm.Bitmap;
                pDisplayBox.SizeMode = PictureBoxSizeMode.StretchImage;
            }
        }

        public void Run(ref Bitmap pImage, int pFrameIndex, int k1, int k2, float pThresholdK1, float pThreshostK2, int pDelta, int pCanDuoiDt, int pCanTrenDt, int pRadius, PictureBox pDisplayBox)
        {
            Lock_bitmap bm = new Lock_bitmap(pImage);
            List doituongList = new List();

            int xCenter = bm.Bitmap.Width / 2;
            int yCenter = bm.Bitmap.Height / 2;
            int minHeight = yCenter - pRadius;
            int maxHeight = yCenter + pRadius;
            int minWidth = xCenter - pRadius;
            int maxWidth = xCenter + pRadius;

            int R2 = pRadius * pRadius;

            matranMark = new int[pImage.Width, pImage.Height];
            for (int i = 0; i < bm.Bitmap.Width; i++)
            {
                for (int j = 0; j < bm.Bitmap.Height; j++)
                {
                    matranMark[i, j] = (i - xCenter) * (i - xCenter) + (j - yCenter) * (j - yCenter) < R2 ? 1 : 0;
                }
            }

            if (pFrameIndex == 1)
            {
                I_frame_4 = new int[pImage.Width, pImage.Height];
                I_frame_3 = new int[pImage.Width, pImage.Height];
                I_frame_2 = new int[pImage.Width, pImage.Height];
                I_frame_1 = new int[pImage.Width, pImage.Height];
                I_frame_0 = new int[pImage.Width, pImage.Height];

                ColorLookup_frame_4 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_3 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_2 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_1 = new int[pImage.Width, pImage.Height];
                ColorLookup_frame_0 = new int[pImage.Width, pImage.Height];

                ColorProb = new float[pImage.Width, pImage.Height];

                //pThresholdK1 = 0.5f;
                Color = new int[pImage.Width, pImage.Height];

                DIFFS = new int[pImage.Width, pImage.Height];

                //Delta_color = new int[pImage.Width, pImage.Height];

                Objectmove = new int[pImage.Width, pImage.Height];
            }
            else
                if (pFrameIndex % pDelta == 0)
                {
                    I_frame_4 = (int[,])I_frame_3.Clone();
                    I_frame_3 = (int[,])I_frame_2.Clone();
                    I_frame_2 = (int[,])I_frame_1.Clone();
                    I_frame_1 = (int[,])I_frame_0.Clone();

                    ColorLookup_frame_4 = (int[,])ColorLookup_frame_3.Clone();
                    ColorLookup_frame_3 = (int[,])ColorLookup_frame_2.Clone();
                    ColorLookup_frame_2 = (int[,])ColorLookup_frame_1.Clone();
                    ColorLookup_frame_1 = (int[,])ColorLookup_frame_0.Clone();

                    bm.LockBitmap();
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            byte red, green, blue;
                            red = bm.GetPixel(i, j).red;
                            green = bm.GetPixel(i, j).green;
                            blue = bm.GetPixel(i, j).blue;

                            // Tra cứu xem màu có phải của đối tượng không.
                            if (ColorLookup(red, green, blue, k1, k2))
                                ColorLookup_frame_0[i, j] = 1;
                            else
                                ColorLookup_frame_0[i, j] = 0;

                            // Tính cường độ sáng tại mỗi điểm ảnh
                            I_frame_0[i, j] = (red + green + blue) / 3;
                        }
                    }

                    bm.UnlockBitmap();

                    // Tính ma trận tần xuất số lần điểm ảnh là đối tượng Colorprob[]
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            ColorProb[i, j] = (float)(ColorLookup_frame_4[i, j] + ColorLookup_frame_3[i, j] +
                                ColorLookup_frame_2[i, j] + ColorLookup_frame_1[i, j] + ColorLookup_frame_0[i, j]) / 5;
                        }
                    }

                    // Tính ma trận xác nhận điểm ảnh nào là đối tượng và lưu trong ma trận Color
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            if (ColorProb[i, j] > pThresholdK1)
                                Color[i, j] = 1;
                            else Color[i, j] = 0;
                        }
                    }

                    // tinh DIFFS
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            DIFFS[i, j] = (Math.Abs(I_frame_0[i, j] - I_frame_1[i, j]) + Math.Abs(I_frame_1[i, j] - I_frame_2[i, j])
                                + Math.Abs(I_frame_2[i, j] - I_frame_3[i, j]) + Math.Abs(I_frame_3[i, j] - I_frame_4[i, j])) / 4;
                        }
                    }

                    //Tinhs nonDiffs
                    float nonDiffs = 0;
                    float SumPointOfnonDiffs = 0;
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            if (Color[i, j] == 0)
                            {
                                nonDiffs += DIFFS[i, j];
                                SumPointOfnonDiffs++;
                            }
                        }
                    }
                    nonDiffs = nonDiffs / SumPointOfnonDiffs;

                    //tinh Object move
                    for (int i = 0; i < bm.Bitmap.Width; i++)
                    {
                        for (int j = 0; j < bm.Bitmap.Height; j++)
                        {
                            // xác định điểm ảnh là đối tượng
                            if ((Color[i, j] == 1) && (DIFFS[i, j] - (int)nonDiffs > pThreshostK2))
                                Objectmove[i, j] = 1;
                            else
                                Objectmove[i, j] = 0;
                        }
                    }

                    // làm đầy ma trận ảnh
                    Utility.LamDayDoiTuong(ref Objectmove, bm.Bitmap.Width, bm.Bitmap.Height, 3, 3, 0.6f);
                    
                    // Sử dụng kỹ thuật gán nhãnh các thành phần liên thông để tìm kiếm đối tượng
                    doituongList = Utility.TimKiemDoiTuongLTNew(Objectmove, bm.Bitmap.Width, bm.Bitmap.Height, minWidth, maxWidth, minHeight, maxHeight, pCanDuoiDt, pCanTrenDt, 0.3f, 3.0f);
                }

            if (pFrameIndex > 5 * pDelta)
            {
                bm.LockBitmap();
                Lock_bitmap.PixelData a;
                a.red = 255; a.green = 0; a.blue = 0;

                //Lock_bitmap.PixelData kh;

                Lock_bitmap.PixelData kh;
                // khoanh vung vong tron
                for (int i = 0; i < bm.Bitmap.Width; i++)
                {
                    for (int j = 0; j < bm.Bitmap.Height; j++)
                    {

                        if (matranMark[i, j] == 0)
                        {
                            kh = bm.GetPixel(i, j);
                            //102, 255, 255
                            kh.red = 102;
                            kh.green = 255;
                            kh.blue = 255;
                            bm.SetPixel(i, j, kh);
                        }
                    }
                }

                // ve tam sung
                Lock_bitmap.PixelData ts, ts1;
                // khoanh vung vong tron
                for (int j = 10; j < bm.Bitmap.Height - 10; j++)
                {
                    for (int i = bm.Bitmap.Width / 2 - 1; i < bm.Bitmap.Width / 2 + 1; i++)
                    {
                        ts = bm.GetPixel(i, j);
                        //102, 255, 255
                        ts.red = ts.green = 0;
                        ts.blue = 255;
                        bm.SetPixel(i, j, ts);
                    }
                }

                for (int i = 10; i < bm.Bitmap.Width - 10; i++)
                {
                    for (int j = bm.Bitmap.Height / 2 - 1; j < bm.Bitmap.Height / 2 + 1; j++)
                    {
                        ts = bm.GetPixel(i, j);
                        //102, 255, 255
                        ts.red = ts.green = 0;
                        ts.blue = 255;
                        bm.SetPixel(i, j, ts);
                    }
                }

                int jStart = yCenter;
                int count = 1;
                while (jStart + 30 * count < maxHeight)
                {
                    for (int i = bm.Bitmap.Width / 2 - 10; i < bm.Bitmap.Width / 2 + 10; i++)
                    {
                        ts = bm.GetPixel(i, jStart + 30 * count);
                        ts1 = bm.GetPixel(i, jStart - 30 * count);
                        //102, 255, 255
                        ts.red = ts.green = 0; ts.blue = 255;
                        ts1.red = ts1.green = 0; ts1.blue = 255;
                        bm.SetPixel(i, jStart + 30 * count, ts);
                        bm.SetPixel(i, jStart - 30 * count, ts1);
                    }
                    count++;
                }

                int iStart = xCenter;
                count = 1;
                while (iStart + 30 * count < maxWidth)
                {
                    for (int j = bm.Bitmap.Height / 2 - 10; j < bm.Bitmap.Height / 2 + 10; j++)
                    {
                        ts = bm.GetPixel(iStart + 30 * count, j);
                        ts1 = bm.GetPixel(iStart - 30 * count, j);
                        //102, 255, 255
                        ts.red = ts.green = 0; ts.blue = 255;
                        ts1.red = ts1.green = 0; ts1.blue = 255;
                        bm.SetPixel(iStart + 30 * count, j, ts);
                        bm.SetPixel(iStart - 30 * count, j, ts1);
                    }
                    count++;
                }


                Utility.KhoanhVungCacDoiTuong(ref bm, minWidth, maxWidth, minHeight, maxHeight, 5, matranMark, doituongList);
               
                bm.UnlockBitmap();
                //current_img = image;
                // image = bm.Bitmap;
                pDisplayBox.Image = bm.Bitmap;

                pDisplayBox.SizeMode = PictureBoxSizeMode.StretchImage;
            }
        }
        /// 
        /// Tim doi tuong dua vao may sac
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public bool ColorLookup(int R, int G, int B, int k1, int k2)
        {
            int gray = Utility.R24ToXam256(R, G, B);
            gray = gray > 255 ? 255 : (gray < 0) ? 0 : gray;
            return gray >= k1 && gray <= k2;
        }
    }

 

Phản hồi