简体   繁体   English

使用 OpenCV\C++ 裁剪图像

[英]Crop image wtih OpenCV\C++

I'm using OpenCV (v 2.4.9.1, Ubuntu 16.04) to do a resize and crop on an image, the original image is a JPEG file with dimensions 640x480.我正在使用 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);

After this I display the images, and it looks perfect - as I would expect it to be:在此之后,我显示图像,它看起来很完美 - 正如我所期望的那样:

在此处输入图像描述

The problem comes when I stream this image, where I notice that the size (in elements) of the cropped image is only a third of what I would expect.当我 stream 这张图片出现问题时,我注意到裁剪后的图片的大小(以元素为单位)仅为我预期的三分之一。 It looks as if there is only one cannel on the resultant crop.看起来好像在所得作物上只有一个通道。 It should have had 224*224*3=150528 , but I'm getting only 50176 when I'm doing它应该有224*224*3=150528 ,但我在做的时候只得到50176

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

Any idea what's wrong here?知道这里有什么问题吗? The type of the resulting cv::Mat looks okay, and also visually it looks ok, so how there is only one channel?生成的cv::Mat的类型看起来不错,在视觉上看起来也不错,那么怎么只有一个通道呢?

Thanks in advance.提前致谢。

Basic Structures — OpenCV 2.4.13.7 documentation says: 基本结构 — OpenCV 2.4.13.7 文档说:

Mat::total垫子::总计

Returns the total number of array elements.返回数组元素的总数。

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

The method returns the number of array elements (a number of pixels if the array represents an image).该方法返回数组元素的数量(如果数组表示图像,则为像素数)。

Therefore, the return value is the number of pixels 224*224=50176 and your expected value is wrong.因此,返回值为像素数224*224=50176 ,您的预期值是错误的。

My terminology was wrong, as pointed by @MikeCAT, and it seems that the issue should be solved in the serialization logic.正如@MikeCAT 所指出的那样,我的术语是错误的,似乎应该在序列化逻辑中解决这个问题。 I went with a solution along the lines of this one: Convert Mat to Array/Vector in OpenCV我采用了一个解决方案: Convert Mat to Array/Vector in OpenCV

My original code didn't check the channels() function.我的原始代码没有检查channels() function。

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM