【问题标题】:How to normalize image in openCV?如何在openCV中标准化图像?
【发布时间】:2017-07-05 03:19:52
【问题描述】:

我是 openCV 的新手,一直卡在某个地方。

我有一个灰度图像,但我需要标准化这个图像。例如:我有一个 cv::mat 图像,它可能有一个包含一些值和每个索引的矩阵。由于我有灰色图像,因此每个索引可能仅包含 1 个值。现在我需要将每个值除以 255。

在 C++ 中的 openCV 中是否有任何可用的方法或工具? 对于这种情况,我相信我要使用的方法在 openCV 中称为归一化?

cv::Mat originalMat = [OSInference cvMatFromUIImage:imgBeforeProccessing];
cv::Mat img2;

cv::cvtColor(originalMat, img2,CV_BGR2GRAY);
cv::resize(img2, img2, cv::Size(128, 128), 0, 0, CV_INTER_CUBIC);
cv::Mat img3;

现在如何归一化(这意味着将矩阵中的每个值除以 255)??

我正在将 mat 图像转换为 iOS 图像,如下所示:

+ (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat{
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];

    CGColorSpaceRef colorspace;

    if (cvMat.elemSize() == 1) {
        colorspace = CGColorSpaceCreateDeviceGray();
    }else{
        colorspace = CGColorSpaceCreateDeviceRGB();
    }

    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

    // Create CGImage from cv::Mat
    CGImageRef imageRef = CGImageCreate(cvMat.cols, cvMat.rows, 8, 8 * cvMat.elemSize(), cvMat.step[0], colorspace, kCGImageAlphaNone | kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);

    // get uiimage from cgimage
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorspace);

    return finalImage;
}

【问题讨论】:

  • THIS
  • 归一化意味着 min -> 0 和 max -> 1

标签: c++ ios objective-c opencv


【解决方案1】:

OpenCV 有一个功能可以完全满足您的需求。它叫做convertTo

cv::Mat img3;
img2.convertTo(img3, CV_32F, 1.0 / 255, 0);

【讨论】:

  • 如果我用我的灰色图像转换成有点颜色的图像(黄色)这可能吗?
  • @sss 我不太明白你的意思
  • 因为我首先将彩色图像转换为灰色,然后应用 convertTo 方法....但在此之后我的图像变黄...根据我的考虑,即使在 convertTo 方法之后,灰色图像也应该保持灰色跨度>
  • 答案是正确的。我认为问题在于UIImageFromCVMat 只处理CV_8U 图像,而这是CV_32F。因此,出于可视化目的,图像的类型应为CV_8U,其值在[0,255]
  • @sss 我看到您使用CGImageCreate 函数进行转换。阅读文档,我认为指定CGColorSpaceCreateDeviceGray 颜色空间和bitsPerComponentbitsPerPixel 的32 可能会有所帮助
【解决方案2】:

要规范化 cv::Mat,您可以使用 cv::normalize。 我写了一些代码来帮助你。

uchar data[] = {0, 63, 127, 255};
cv::Mat im(2, 2, CV_8UC1, data), output;
# this what you need 0 -> min value after norm
# 1 -> max value after nom
# cv::NORM_MINMAX normalize for min and max values
cv::normalize(im, output, 0, 1, cv::NORM_MINMAX);
std::cout 
    << im     << '\n'
    << output << '\n';
#==================================================
# output
[  0,  63;
   127, 255]
[  0,   0;
   0,   1]

【讨论】:

  • 规范化概念和我想要的一样吗?
  • @sss 我相信它的行为与我的答案中的解决方案相同,但它还必须计算因子(1/255)才能将所有值乘以自身(参见docs
  • @slawekwin 这与您的问题不同(实际上不正确)。仅当输入图像恰好同时具有 0 和 255 值时才相同,否则缩放因子不是1/255
猜你喜欢
  • 2016-10-27
  • 2017-03-31
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 2020-10-09
  • 2014-06-03
相关资源
最近更新 更多