Ejemplo n.º 1
0
        /// <summary>
        /// Converts a byte array from BGR to RGB.
        /// </summary>
        static byte[] EncodingConversion(ImageMsg image, bool convertBGR = true, bool flipY = true)
        {
            // Number of channels in this encoding
            int channels = image.GetNumChannels();

            if (!image.EncodingRequiresBGRConversion())
            {
                convertBGR = false;
            }

            // If no modifications are necessary, return original array
            if (!convertBGR && !flipY)
            {
                return(image.data);
            }

            int channelStride = image.GetBytesPerChannel();
            int pixelStride   = channelStride * channels;
            int rowStride     = pixelStride * (int)image.width;

            if (flipY)
            {
                ReverseInBlocks(image.data, rowStride, (int)image.height);
            }

            if (convertBGR)
            {
                // given two channels, we swap R with G (distance = 1).
                // given three or more channels, we swap R with B (distance = 2).
                int swapDistance = channels == 2 ? channelStride : channelStride * 2;
                int dataLength   = (int)image.width * (int)image.height * pixelStride;

                if (channelStride == 1)
                {
                    // special case for the 1-byte-per-channel formats: avoid the inner loop
                    for (int pixelIndex = 0; pixelIndex < dataLength; pixelIndex += pixelStride)
                    {
                        int  swapB = pixelIndex + swapDistance;
                        byte temp  = image.data[pixelIndex];
                        image.data[pixelIndex] = image.data[swapB];
                        image.data[swapB]      = temp;
                    }
                }
                else
                {
                    for (int pixelIndex = 0; pixelIndex < dataLength; pixelIndex += pixelStride)
                    {
                        int channelEndByte = pixelIndex + channelStride;
                        for (int byteIndex = pixelIndex; byteIndex < channelEndByte; byteIndex++)
                        {
                            int  swapB = byteIndex + swapDistance;
                            byte temp  = image.data[byteIndex];
                            image.data[byteIndex] = image.data[swapB];
                            image.data[swapB]     = temp;
                        }
                    }
                }
            }
            return(image.data);
        }
Ejemplo n.º 2
0
        public static void DebayerConvert(this ImageMsg image, bool flipY = true)
        {
            int channelStride    = image.GetBytesPerChannel();
            int width            = (int)image.width;
            int height           = (int)image.height;
            int rowStride        = width * channelStride;
            int dataSize         = rowStride * height;
            int finalPixelStride = channelStride * 4;

            int[] reorderIndices;
            switch (image.encoding)
            {
            case "bayer_rggb8":
                reorderIndices = new int[] { 0, 1, width + 1 };
                break;

            case "bayer_bggr8":
                reorderIndices = new int[] { width + 1, 1, 0 };
                break;

            case "bayer_gbrg8":
                reorderIndices = new int[] { width, 0, 1 };
                break;

            case "bayer_grbg8":
                reorderIndices = new int[] { 1, 0, width };
                break;

            case "bayer_rggb16":
                reorderIndices = new int[] { 0, 1, 2, 3, rowStride + 2, rowStride + 3 };
                break;

            case "bayer_bggr16":
                reorderIndices = new int[] { rowStride + 2, rowStride + 3, 2, 3, 0, 1 };
                break;

            case "bayer_gbrg16":
                reorderIndices = new int[] { rowStride, rowStride + 1, 0, 1, 2, 3 };
                break;

            case "bayer_grbg16":
                reorderIndices = new int[] { 2, 3, 0, 1, rowStride, rowStride + 1 };
                break;

            default:
                return;
            }

            if (flipY)
            {
                ReverseInBlocks(image.data, rowStride * 2, (int)image.height / 2);
            }

            if (s_ScratchSpace == null || s_ScratchSpace.Length < rowStride * 2)
            {
                s_ScratchSpace = new byte[rowStride * 2];
            }

            int rowStartIndex = 0;

            while (rowStartIndex < dataSize)
            {
                Buffer.BlockCopy(image.data, rowStartIndex, s_ScratchSpace, 0, rowStride * 2);
                int pixelReadIndex  = 0;
                int pixelWriteIndex = rowStartIndex;
                while (pixelReadIndex < rowStride)
                {
                    for (int Idx = 0; Idx < reorderIndices.Length; ++Idx)
                    {
                        image.data[pixelWriteIndex + Idx] = s_ScratchSpace[pixelReadIndex + reorderIndices[Idx]];
                    }
                    image.data[pixelWriteIndex + reorderIndices.Length] = 255;
                    if (channelStride == 2)
                    {
                        image.data[pixelWriteIndex + reorderIndices.Length + 1] = 255;
                    }
                    pixelReadIndex  += channelStride * 2;
                    pixelWriteIndex += finalPixelStride;
                }
                rowStartIndex += rowStride * 2;
            }

            image.width    = image.width / 2;
            image.height   = image.height / 2;
            image.encoding = channelStride == 1 ? "rgba8" : "rgba16";
            image.step     = (uint)(channelStride * image.width);
        }