通过OpenCV \ C ++裁剪图像

时间:2020-06-28 08:56:22

标签: c++ opencv

我正在使用OpenCV(v 2.4.9.1,Ubuntu 16.04)对图像进行调整大小和裁剪,原始图像是尺寸为640x480的JPEG文件。

cv::Mat _aspect_preserving_resize(const cv::Mat& image, int target_width)
{
    cv::Mat output;
    int min_dim = ( image.cols >= image.rows ) ? image.rows : image.cols;
    float scale = ( ( float ) target_width ) / min_dim;
    cv::resize( image, output, cv::Size(int(image.cols*scale), int(image.rows*scale)));
    return output;
}

cv::Mat _center_crop(cv::Mat& image, cv::Size& input_size) 
{
    cv::Rect myROI(int(image.cols/2-input_size.width/2), int(image.rows/2-input_size.height/2), input_size.width, input_size.height);
    cv::Mat croppedImage = image(myROI);
    return croppedImage;
}

int min_input_size = int(input_size.height * 1.14);
cv::Mat image = cv::imread("power-dril/47105738371_72f83eeb37_z.jpg");
cv::Mat output = _aspect_preserving_resize(image, min_input_size);
cv::Mat result = _center_crop(output, input_size);

此后,我显示图像,并且看起来很完美-如我所愿:

enter image description here

当我流处理此图像时出现问题,我注意到裁剪后的图像的大小(以元素为单位)仅为我期望值的三分之一。看起来结果作物上只有一个漏斗。它应该有224*224*3=150528,但是我在做的时候只得到50176

std::cout << cropped_image.total() << " " << cropped_image.type() << endl;
>>> 50176 16

有什么想法吗?生成的cv::Mat的类型看起来还不错,而且在视觉上看起来还不错,所以怎么只有一个频道?

谢谢。

2 个答案:

答案 0 :(得分:0)

Basic Structures — OpenCV 2.4.13.7 documentation说:

Mat :: total

返回数组元素的总数。

C ++:size_t Mat :: total()const

该方法返回数组元素的数量(如果 数组代表一张图片。

因此,返回值是像素数224*224=50176,而您的期望值是错误的。

答案 1 :(得分:0)

正如@MikeCAT所指出的,我的术语是错误的,似乎应该在序列化逻辑中解决该问题。我遵循了一个解决方案: Convert Mat to Array/Vector in OpenCV

我的原始代码未检查channels()函数。

if (curr_img.isContinuous()) {
    int totalsz = curr_img.dataend-curr_img.datastart;
    array.assign(curr_img.datastart, curr_img.datastart + totalsz);
} else {
    int rowsz = CV_ELEM_SIZE(curr_img.type()) * curr_img.cols;
    for (int i = 0; i < curr_img.rows; ++i) {
        array.insert(array.end(), curr_img.ptr<uint8_t>(i), curr_img.ptr<uint8_t>(i) + rowsz);
    }
}