โครงสร้างการเก็บข้อมูลพิกเซล ที่เราได้มาจาก Kinect ด้วยคำสั่ง colorFrame.CopyPixelDataTo(colorData); นั้น จะเป็นข้อมูลแบบไบต์ (byte) ที่เก็บในอาร์เรย์หนึ่งมิติ โดยหนึ่งพิกเซลจะประกอบไปด้วยอาร์เรย์สี่ช่อง แบบ BGRA นั่นคือ
0-Blue
1-Green
2-Red
3-Alpha
โดยเลข 0,1,2,... เป็น index ของอาร์เรย์ และวนไปเรื่อยๆ คือ 4-Blue, 5-Green, 6-Red, 7-Alpha...
แต่ละช่องสีก็จะถูกเก็บด้วยตัวแปรชนิดไบต์ นั่นคือ 1 ช่องสี = 1 byte = 8 bits และเก็บค่าช่วงสีได้ 2^8 = 256 ค่า (0-255) ดังนั้น หนึ่งพิกเซลจะใช้อาร์เรย์ 4 ช่อง = 4 bytes = 32 bits
ในที่นี้ เราจะลองมาเปลี่ยนค่าสีของพิกเซล โดยสร้างภาพกลับสี (Negative) กันครับ หลักการคือถ้าอ่านค่าสีพิกเซลได้เท่าใด ให้นำไปหักออกจาก 255 ก็จะได้ค่าสีที่อยู่ตรงข้ามครับ
สมมติว่ารูปปกติคือ
ตัวอย่างผลลัพธ์ที่ได้ก็จะเป็น
การแก้ไขก็จะแก้เฉพาะส่วนของ byte array ก่อนที่จะสร้างบิตแมพ ซึ่งจะแก้ในเฉพาะส่วนของฟังก์ชันที่เป็นผลของ ColorFrameReady ดังนี้ครับ
สังเกตว่าส่วนที่แก้ไขมีนิดเดียว อยู่ระหว่าเส้นประที่ขีดไว้ครับ
void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) { using (ColorImageFrame colorFrame = e.OpenColorImageFrame()) { //if get new video frame if (colorFrame == null) return; //create an array of pixel data if(colorData==null) colorData = new byte[colorFrame.PixelDataLength]; //extract pixel data from the frame to the array colorFrame.CopyPixelDataTo(colorData); //------------------------------------------------------ //modify the pixel data //0=Blue,1=Green,2=Red,3=Alpha for (int i = 0; i < colorData.Length; i = i + 4) { //image negative //blue colorData[i] = (byte)(255 - colorData[i]); //green colorData[i + 1] = (byte)(255 - colorData[i + 1]); //red colorData[i + 2] = (byte)(255 - colorData[i + 2]); } //------------------------------------------------------ //For the first video frame, no bitmap, create a writable bitmap of video size if (imageBitmap == null) { imageBitmap = new WriteableBitmap( colorFrame.Width, colorFrame.Height, 96, //dpiX 96, //dpiY PixelFormats.Bgr32, null //palette:none ); } //For other video frames, write video data to bitmap imageBitmap.WritePixels( new Int32Rect(0, 0, colorFrame.Width, colorFrame.Height), colorData, //video data colorFrame.Width * colorFrame.BytesPerPixel, //stride 0 //offset to the array ); //set bitmap to image view kinectVideo.Source = imageBitmap; } }
No comments:
Post a Comment