CommonUtility.cpp 5.93 KB
Newer Older
liucong's avatar
liucong committed
1
2
3
4
5
6
7
8
#include <CommonUtility.h>

using namespace cv;
using namespace cv::dnn;

namespace migraphxSamples
{

liucong's avatar
liucong committed
9
10
11
void blobFromImagesWithParams(InputArrayOfArrays images_,
                              OutputArray blob_,
                              const Image2BlobParams& param)
liucong's avatar
liucong committed
12
{
liucong's avatar
liucong committed
13
14
15
16
    if(images_.kind() != _InputArray::STD_VECTOR_MAT &&
       images_.kind() != _InputArray::STD_ARRAY_MAT &&
       images_.kind() != _InputArray::STD_VECTOR_VECTOR)
    {
liucong's avatar
liucong committed
17
18
19
        String error_message = "The data is expected as vectors of vectors or vectors of matrices.";
        CV_Error(Error::StsBadArg, error_message);
    }
liucong's avatar
liucong committed
20
21
    CV_CheckType(param.ddepth,
                 param.ddepth == CV_32F || param.ddepth == CV_8U,
liucong's avatar
liucong committed
22
23
24
25
26
27
                 "Blob depth should be CV_32F or CV_8U");
    Size size = param.size;
    std::vector<Mat> images;
    images_.getMatVector(images);
    CV_Assert(!images.empty());

liucong's avatar
liucong committed
28
    int nch            = images[0].channels();
liucong's avatar
liucong committed
29
30
    Scalar scalefactor = param.scalefactor;

liucong's avatar
liucong committed
31
    if(param.ddepth == CV_8U)
liucong's avatar
liucong committed
32
    {
liucong's avatar
liucong committed
33
34
35
36
        CV_Assert(scalefactor == Scalar::all(1.0) &&
                  "Scaling is not supported for CV_8U blob depth");
        CV_Assert(param.mean == Scalar() &&
                  "Mean subtraction is not supported for CV_8U blob depth");
liucong's avatar
liucong committed
37
38
    }

liucong's avatar
liucong committed
39
    for(size_t i = 0; i < images.size(); i++)
liucong's avatar
liucong committed
40
41
    {
        Size imgSize = images[i].size();
liucong's avatar
liucong committed
42
        if(size == Size())
liucong's avatar
liucong committed
43
            size = imgSize;
liucong's avatar
liucong committed
44
        if(size != imgSize)
liucong's avatar
liucong committed
45
        {
liucong's avatar
liucong committed
46
            if(param.paddingmode == DNN_PMODE_CROP_CENTER)
liucong's avatar
liucong committed
47
48
49
50
51
52
53
54
55
56
57
            {
                float resizeFactor = std::max(size.width / (float)imgSize.width,
                                              size.height / (float)imgSize.height);
                resize(images[i], images[i], Size(), resizeFactor, resizeFactor, INTER_LINEAR);
                Rect crop(Point(0.5 * (images[i].cols - size.width),
                                0.5 * (images[i].rows - size.height)),
                          size);
                images[i] = images[i](crop);
            }
            else
            {
liucong's avatar
liucong committed
58
                if(param.paddingmode == DNN_PMODE_LETTERBOX)
liucong's avatar
liucong committed
59
60
61
                {
                    float resizeFactor = std::min(size.width / (float)imgSize.width,
                                                  size.height / (float)imgSize.height);
liucong's avatar
liucong committed
62
63
                    int rh             = int(imgSize.height * resizeFactor);
                    int rw             = int(imgSize.width * resizeFactor);
liucong's avatar
liucong committed
64
65
                    resize(images[i], images[i], Size(rw, rh), INTER_LINEAR);

liucong's avatar
liucong committed
66
                    int top    = (size.height - rh) / 2;
liucong's avatar
liucong committed
67
                    int bottom = size.height - top - rh;
liucong's avatar
liucong committed
68
69
                    int left   = (size.width - rw) / 2;
                    int right  = size.width - left - rw;
liucong's avatar
liucong committed
70
71
72
73
74
75
76
77
                    copyMakeBorder(images[i], images[i], top, bottom, left, right, BORDER_CONSTANT);
                }
                else
                    resize(images[i], images[i], size, 0, 0, INTER_LINEAR);
            }
        }

        Scalar mean = param.mean;
liucong's avatar
liucong committed
78
        if(param.swapRB)
liucong's avatar
liucong committed
79
80
81
82
83
        {
            std::swap(mean[0], mean[2]);
            std::swap(scalefactor[0], scalefactor[2]);
        }

liucong's avatar
liucong committed
84
        if(images[i].depth() == CV_8U && param.ddepth == CV_32F)
liucong's avatar
liucong committed
85
86
87
88
89
90
91
            images[i].convertTo(images[i], CV_32F);

        images[i] -= mean;
        multiply(images[i], scalefactor, images[i]);
    }

    size_t nimages = images.size();
liucong's avatar
liucong committed
92
    Mat image0     = images[0];
liucong's avatar
liucong committed
93
94
    CV_Assert(image0.dims == 2);

liucong's avatar
liucong committed
95
    if(param.datalayout == DNN_LAYOUT_NCHW)
liucong's avatar
liucong committed
96
    {
liucong's avatar
liucong committed
97
        if(nch == 3 || nch == 4)
liucong's avatar
liucong committed
98
        {
liucong's avatar
liucong committed
99
            int sz[] = {(int)nimages, nch, image0.rows, image0.cols};
liucong's avatar
liucong committed
100
101
102
103
            blob_.create(4, sz, param.ddepth);
            Mat blob = blob_.getMat();
            Mat ch[4];

liucong's avatar
liucong committed
104
            for(size_t i = 0; i < nimages; i++)
liucong's avatar
liucong committed
105
106
107
108
109
110
111
            {
                const Mat& image = images[i];
                CV_Assert(image.depth() == blob_.depth());
                nch = image.channels();
                CV_Assert(image.dims == 2 && (nch == 3 || nch == 4));
                CV_Assert(image.size() == image0.size());

liucong's avatar
liucong committed
112
                for(int j = 0; j < nch; j++)
liucong's avatar
liucong committed
113
                    ch[j] = Mat(image.rows, image.cols, param.ddepth, blob.ptr((int)i, j));
liucong's avatar
liucong committed
114
                if(param.swapRB)
liucong's avatar
liucong committed
115
116
117
118
119
120
121
                    std::swap(ch[0], ch[2]);
                split(image, ch);
            }
        }
        else
        {
            CV_Assert(nch == 1);
liucong's avatar
liucong committed
122
            int sz[] = {(int)nimages, 1, image0.rows, image0.cols};
liucong's avatar
liucong committed
123
124
125
            blob_.create(4, sz, param.ddepth);
            Mat blob = blob_.getMat();

liucong's avatar
liucong committed
126
            for(size_t i = 0; i < nimages; i++)
liucong's avatar
liucong committed
127
128
129
130
131
132
133
134
135
136
137
            {
                const Mat& image = images[i];
                CV_Assert(image.depth() == blob_.depth());
                nch = image.channels();
                CV_Assert(image.dims == 2 && (nch == 1));
                CV_Assert(image.size() == image0.size());

                image.copyTo(Mat(image.rows, image.cols, param.ddepth, blob.ptr((int)i, 0)));
            }
        }
    }
liucong's avatar
liucong committed
138
    else if(param.datalayout == DNN_LAYOUT_NHWC)
liucong's avatar
liucong committed
139
    {
liucong's avatar
liucong committed
140
        int sz[] = {(int)nimages, image0.rows, image0.cols, nch};
liucong's avatar
liucong committed
141
        blob_.create(4, sz, param.ddepth);
liucong's avatar
liucong committed
142
        Mat blob       = blob_.getMat();
liucong's avatar
liucong committed
143
        int subMatType = CV_MAKETYPE(param.ddepth, nch);
liucong's avatar
liucong committed
144
        for(size_t i = 0; i < nimages; i++)
liucong's avatar
liucong committed
145
146
147
148
149
        {
            const Mat& image = images[i];
            CV_Assert(image.depth() == blob_.depth());
            CV_Assert(image.channels() == image0.channels());
            CV_Assert(image.size() == image0.size());
liucong's avatar
liucong committed
150
            if(param.swapRB)
liucong's avatar
liucong committed
151
152
153
154
155
156
157
158
159
160
            {
                Mat tmpRB;
                cvtColor(image, tmpRB, COLOR_BGR2RGB);
                tmpRB.copyTo(Mat(tmpRB.rows, tmpRB.cols, subMatType, blob.ptr((int)i, 0)));
            }
            else
                image.copyTo(Mat(image.rows, image.cols, subMatType, blob.ptr((int)i, 0)));
        }
    }
    else
liucong's avatar
liucong committed
161
162
        CV_Error(Error::StsUnsupportedFormat,
                 "Unsupported data layout in blobFromImagesWithParams function.");
liucong's avatar
liucong committed
163
164
}

liucong's avatar
liucong committed
165
} // namespace migraphxSamples