Resizing the image in C# and sending it to OpenCV results in distorted image

后端 未结 1 1543
温柔的废话
温柔的废话 2021-01-16 06:45

This is a follow-up question related to this one. Basically, I have a DLL which uses OpenCV to do image manipulation. There are two methods, one accepting an image-Pat

1条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-16 07:28

    What I did was to use imdecode as EdChum suggested. This is how the functions in the DLL and C# look now:

    #ifdef CDLL2_EXPORTS
    #define CDLL2_API __declspec(dllexport)
    #else
    #define CDLL2_API __declspec(dllimport)
    #endif
    
    #include "classification.h" 
    extern "C"
    {
        CDLL2_API void Classify_Image(unsigned char* img_pointer, long data_len, char* out_result, int* length_of_out_result, int top_n_results = 2);
    //...
    }
    

    The actual method:

    CDLL2_API void Classify_Image(unsigned char* img_pointer, long data_len,
                                  char* out_result, int* length_of_out_result, int top_n_results)
    {
        auto classifier = reinterpret_cast(GetHandle());
        vector inputImageBytes(img_pointer, img_pointer + data_len);
        cv::Mat img = imdecode(inputImageBytes, CV_LOAD_IMAGE_COLOR);
    
        cv::imshow("img just recieved from c#", img);
    
        std::vector result = classifier->Classify(img, top_n_results);
        //...
        *length_of_out_result = ss.str().length();
    }
    

    Here is the C# DllImport:

    [DllImport(@"CDll2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    static extern void Classify_Image(byte[] img, long data_len, byte[] out_result, out int out_result_length, int top_n_results = 2);
    

    and this is the actual method sending the image back to the DLL:

    private string Classify_UsingImage(Bitmap image, int top_n_results)
    {
        byte[] result = new byte[200];
        int len;
        Bitmap img;
    
        if (chkResizeImageCShap.Checked)
            img = ResizeImage(image, int.Parse(txtWidth.Text), (int.Parse(txtHeight.Text)));
        else
            img = image;
    
        //this is for situations, where the image is not read from disk, and is stored in the memort(e.g. image comes from a camera or snapshot)
        ImageFormat fmt = new ImageFormat(image.RawFormat.Guid);
        var imageCodecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(codec => codec.FormatID == image.RawFormat.Guid);
        if (imageCodecInfo == null)
        {
            fmt = ImageFormat.Jpeg;
        }
    
        using (MemoryStream ms = new MemoryStream())
        {
            img.Save(ms, fmt);
            byte[] image_byte_array = ms.ToArray();
            Classify_Image(image_byte_array, ms.Length, result, out len, top_n_results);
        }
    
        return ASCIIEncoding.ASCII.GetString(result);
    }
    

    By doing this after resizing the image from C#, we don't face any distortions at all.

    I couldn't, however, figure out why the resize on OpenCV part wouldn't work as expected!

    0 讨论(0)
提交回复
热议问题