मैं कुछ कोड लिखने का प्रयास कर रहा हूं जो तेजी से वीडियो फ्रेम को संसाधित करेगा। मैं फ्रेम को System.Windows.Media.Imaging.WriteableBitmap
के रूप में प्राप्त कर रहा हूं। परीक्षण उद्देश्यों के लिए, मैं बस एक साधारण थ्रेसहोल्ड फ़िल्टर लागू कर रहा हूं जो बीजीआरए प्रारूप छवि को संसाधित करेगा और प्रत्येक पिक्सेल को बीजीआर पिक्सेल के औसत के आधार पर काला या सफेद रंग देने के लिए असाइन करेगा।मेरे सुरक्षित कोड से मेरा असुरक्षित कोड ब्लॉक धीमा क्यों है?
यहाँ मेरी "सुरक्षित" संस्करण है:
public static void ApplyFilter(WriteableBitmap Bitmap, byte Threshold)
{
// Let's just make this work for this format
if (Bitmap.Format != PixelFormats.Bgr24
&& Bitmap.Format != PixelFormats.Bgr32)
{
return;
}
// Calculate the number of bytes per pixel (should be 4 for this format).
var bytesPerPixel = (Bitmap.Format.BitsPerPixel + 7)/8;
// Stride is bytes per pixel times the number of pixels.
// Stride is the byte width of a single rectangle row.
var stride = Bitmap.PixelWidth * bytesPerPixel;
// Create a byte array for a the entire size of bitmap.
var arraySize = stride * Bitmap.PixelHeight;
var pixelArray = new byte[arraySize];
// Copy all pixels into the array
Bitmap.CopyPixels(pixelArray, stride, 0);
// Loop through array and change pixels to black/white based on threshold
for (int i = 0; i < pixelArray.Length; i += bytesPerPixel)
{
// i=B, i+1=G, i+2=R, i+3=A
var brightness =
(byte)((pixelArray[i] + pixelArray[i+1] + pixelArray[i+2])/3);
var toColor = byte.MinValue; // Black
if (brightness >= Threshold)
{
toColor = byte.MaxValue; // White
}
pixelArray[i] = toColor;
pixelArray[i + 1] = toColor;
pixelArray[i + 2] = toColor;
}
Bitmap.WritePixels(
new Int32Rect(0, 0, Bitmap.PixelWidth, Bitmap.PixelHeight),
pixelArray, stride, 0
);
}
यहाँ है मैं क्या सोचता एक असुरक्षित कोड ब्लॉक और forebuffer के बजाय WriteableBitmap वापस बफर का उपयोग कर एक सीधा अनुवाद है:
public static void ApplyFilterUnsafe(WriteableBitmap Bitmap, byte Threshold)
{
// Let's just make this work for this format
if (Bitmap.Format != PixelFormats.Bgr24
&& Bitmap.Format != PixelFormats.Bgr32)
{
return;
}
var bytesPerPixel = (Bitmap.Format.BitsPerPixel + 7)/8;
Bitmap.Lock();
unsafe
{
// Get a pointer to the back buffer.
byte* pBackBuffer = (byte*)Bitmap.BackBuffer;
for (int i = 0;
i < Bitmap.BackBufferStride*Bitmap.PixelHeight;
i+= bytesPerPixel)
{
var pCopy = pBackBuffer;
var brightness = (byte)((*pBackBuffer
+ *++pBackBuffer
+ *++pBackBuffer)/3);
pBackBuffer++;
var toColor =
brightness >= Threshold ? byte.MaxValue : byte.MinValue;
*pCopy = toColor;
*++pCopy = toColor;
*++pCopy = toColor;
}
}
// Bitmap.AddDirtyRect(
// new Int32Rect(0,0, Bitmap.PixelWidth, Bitmap.PixelHeight));
Bitmap.Unlock();
}
यह असुरक्षित कोड ब्लॉक और पॉइंटर्स में मेरा पहला प्रयास है, इसलिए शायद तर्क इष्टतम नहीं है।
मैं एक ही WriteableBitmaps के प्रयोग पर कोड के दोनों ब्लॉकों का परीक्षण किया है:
var threshold = Convert.ToByte(op.Result);
var copy2 = copyFrame.Clone();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
BinaryFilter.ApplyFilterUnsafe(copyFrame, threshold);
stopWatch.Stop();
var unsafesecs = stopWatch.ElapsedMilliseconds;
stopWatch.Reset();
stopWatch.Start();
BinaryFilter.ApplyFilter(copy2, threshold);
stopWatch.Stop();
Debug.WriteLine(string.Format("Unsafe: {1}, Safe: {0}",
stopWatch.ElapsedMilliseconds, unsafesecs));
तो मैं एक ही छवि का विश्लेषण कर रहा हूँ। वीडियो फ्रेम की आने वाली स्ट्रीम का परीक्षण रन:
Unsafe: 110, Safe: 53
Unsafe: 136, Safe: 42
Unsafe: 106, Safe: 36
Unsafe: 95, Safe: 43
Unsafe: 98, Safe: 41
Unsafe: 88, Safe: 36
Unsafe: 129, Safe: 65
Unsafe: 100, Safe: 47
Unsafe: 112, Safe: 50
Unsafe: 91, Safe: 33
Unsafe: 118, Safe: 42
Unsafe: 103, Safe: 80
Unsafe: 104, Safe: 34
Unsafe: 101, Safe: 36
Unsafe: 154, Safe: 83
Unsafe: 134, Safe: 46
Unsafe: 113, Safe: 76
Unsafe: 117, Safe: 57
Unsafe: 90, Safe: 41
Unsafe: 156, Safe: 35
मेरा असुरक्षित संस्करण हमेशा धीमा क्यों है? क्या यह बैक बफर का उपयोग करने के कारण है? या मुझ से कुछ गलत हो रहा है?
धन्यवाद
मदद करता है क्या आप इन परीक्षणों को रिलीज बिल्ड में चला रहे हैं? –
नहीं यह अभी डिबगर निर्माण में है। –
मैं सार्थक परिणाम प्राप्त करने के लिए रिलीज बिल्ड में प्रदर्शन परीक्षण परीक्षण की अनुशंसा करता हूं। यदि आप ऑप्टिमाइज़र को कोड के साथ अपना रास्ता देते हैं तो आप एक 'असुरक्षित' संस्करण का उपयोग करके औचित्य साबित करने के लिए प्रदर्शन प्रदर्शन कम कर सकते हैं। –