Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用OpenCV C+;将24位深度的PNG图像转换为8位深度的PNG图像+;_C++_Image_Opencv - Fatal编程技术网

C++ 如何使用OpenCV C+;将24位深度的PNG图像转换为8位深度的PNG图像+;

C++ 如何使用OpenCV C+;将24位深度的PNG图像转换为8位深度的PNG图像+;,c++,image,opencv,C++,Image,Opencv,我想将24位png图像转换为8位png图像 我尝试了几种方法,但都失败了 我想将彩色24位png_图像转换为彩色8位png_图像 但是,如果我尝试转换为8位图像,它会变成灰度。 我想使用一个imwrite()。但任何东西都不重要 下面是我的完整代码 #include <oppencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <o

我想将24位png图像转换为8位png图像

我尝试了几种方法,但都失败了

我想将彩色24位png_图像转换为彩色8位png_图像

但是,如果我尝试转换为8位图像,它会变成灰度。

我想使用一个imwrite()。但任何东西都不重要

下面是我的完整代码

#include <oppencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp> //for resize
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <stdio.h>

using namespace cv;
using namespace std;

void overlayImage(const Mat &background, const Mat &foreground, Mat &output, 
Point2i location);

int main(int argc, char** argv)
{

    Mat image_background;
    Mat black_background;
    Mat image_target, image_segmentation;

    image_target = imread("panda.png", IMREAD_UNCHANGED);   //  Transparent PNG


    image_segmentation = imread("panda_segmentation_stroke.png", IMREAD_UNCHANGED);

    string filename, filename2;

    vector<String> fn;

    glob("C:\\Users\\IMRC\\source\\repos\\OpenCVProject\\OpenCVProject\\background\\*.jpg", fn, false);

    size_t count = fn.size();
    cout << "Image Size " << count << "\n";

    float MIN_SIZE = 0.3;
    float MAX_SIZE = 0.8;

    float WIDTH = 300;
    float HEIGHT = 400;
    float SIZE_WIDTH, SIZE_HEIGHT, Point_x, Point_y;  // random size and point 


    string JPEGImagesPath = "C:\\Users\\IMRC\\DESKTOP\\TEST\\JPEGImages\\2019-";
    string SEG_ImagesPath = "C:\\Users\\IMRC\\DESKTOP\\TEST\\SegmentationClass\\2019-";

    srand(static_cast <unsigned> (time(0)));

    black_background = imread(fn[0], IMREAD_COLOR);
    resize(black_background, black_background, Size(500, 500));

    for (size_t i = 0; i < count; i++) {
        cout << fn[i] << "\n";

        image_background = imread(fn[i], IMREAD_COLOR);                           
        black_background.setTo(Scalar(0, 0, 0));

        resize(image_background, image_background, Size(500,500));                    // background image resize

        Mat image_resize_target;
        Mat image_resize_segmentation;


        SIZE_WIDTH = MIN_SIZE + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX / (MAX_SIZE - MIN_SIZE)));
        SIZE_HEIGHT = MIN_SIZE + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (MAX_SIZE - MIN_SIZE)));

        Point_x = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / WIDTH));
        Point_y = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / HEIGHT));

        resize(image_target, image_resize_target, Size(), SIZE_WIDTH, SIZE_HEIGHT);                
        resize(image_segmentation, image_resize_segmentation, Size(), SIZE_WIDTH, SIZE_HEIGHT);

        overlayImage(image_background, image_resize_target, image_background, cv::Point(Point_x, Point_y));
        overlayImage(black_background, image_resize_segmentation, black_background, cv::Point(Point_x, Point_y));


        stringstream JPEGImages, SEG_Images, SEG_RawImage;
        JPEGImages   << JPEGImagesPath    << i + 1 << ".jpg";
        SEG_Images   << SEG_ImagesPath    << i + 1 << ".png";

        filename = JPEGImages.str();
        imwrite(filename, image_background);  // save JPEGImages

        filename2 = SEG_Images.str();   
        imwrite(filename2, black_background); // save SegmentationClass

    }

    return 0;
}

void overlayImage(const Mat &background, const Mat &foreground, Mat &output, Point2i location)
{
    background.copyTo(output);

    // start at the row indicated by location, or at row 0 if location.y is negative.
    for (int y = std::max(location.y, 0); y < background.rows; ++y)
    {
    int fY = y - location.y;   // because of the translation

    if (fY >= foreground.rows) // we are done of we have processed all rows of the foreground image.
        break;

    // start at the column indicated by location, 

    // or at column 0 if location.x is negative.
    for (int x = std::max(location.x, 0); x < background.cols; ++x)
    {
        int fX = x - location.x;    // because of the translation.

        if (fX >= foreground.cols)  // we are done with this row if the column is outside of the foreground image.
            break;

        // determine the opacity of the foregrond pixel, using its fourth (alpha) channel.
        double opacity = ((double)foreground.data[fY * foreground.step + fX * foreground.channels() + 3]) / 255.;
            // and now combine the background and foreground pixel, using the opacity, 

            // but only if opacity > 0.
            for (int c = 0; opacity > 0 && c < output.channels(); ++c)
            {
                unsigned char foregroundPx = foreground.data[fY * foreground.step + fX * foreground.channels() + c];
                unsigned char backgroundPx = background.data[y * background.step + x * background.channels() + c];
                output.data[y*output.step + output.channels()*x + c] = backgroundPx * (1. - opacity) + foregroundPx * opacity;
            }
        }
    }
}
#包括
#包括
#包括
#包含//以调整大小
#包括
#包括
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
无效覆盖图像(常量贴图和背景、常量贴图和前景、贴图和输出、,
点2i位置);
int main(int argc,字符**argv)
{
Mat图像背景;
Mat黑底;
Mat图像目标,图像分割;
image_target=imread(“panda.png”,imread_不变);//透明png
image\u segmentation=imread(“panda\u segmentation\u stroke.png”,imread\u未更改);
字符串文件名,filename2;
向量fn;
glob(“C:\\Users\\IMRC\\source\\repos\\OpenCVProject\\OpenCVProject\\background\\*.jpg”,fn,false);
size_t count=fn.size();
cout您可以使用函数更改
cv::Mat
的类型。我假设您要转换为8位图像的图像类型为
cv\u 32SC3
(或者
cv\u 32SC4
,如果您有alpha通道)。即使我的猜测不正确,您也可以使用来学习正确的图像类型。然后,您可以使用上面的第一个函数将图像转换为
CV_8UC3
。请注意,转换函数接受缩放因子
alpha
。这应该正确设置,否则会导致整数溢出。您可以计算出装备根据
cv::Mat::type()
提供的内容确定ht比例因子。希望这对您有所帮助

编辑:您可以检查
type()
的结果是什么意思


的大纲说明,在编写
PNG
文件时,唯一可以调整的参数是图像质量。更改OpenCV图像的通道数是设置图像属性的唯一第二种方法,我们已经在上面讨论过。因此,只有通过使用调色板才能获得8位彩色PNG。请选中de>libpng
的文档说明。

谢谢你的回答。我使用
得到了16个结果,我可以在答案中添加一个链接吗。显然你的图像有三个通道,并且已经达到了8位分辨率。你能更清楚地理解8位PNG是什么意思吗?哦,我很抱歉。我添加了一张图片。用我国家的语言,我t仅作为图像位写入。当我将语言切换为英语进行捕获时,它是位深度。对此我该怎么办?
24位
,指的是
24位像素大小
8位每个颜色通道
。您是指带有调色板的单通道图像(如PNG格式)不能用OpenCV编写,因为你在C++中,直接使用LBPNG是你的方法。你想要的过程叫做抖动,而OpenCV文档的快速搜索并没有发现任何东西——显然这个普通函数没有提供。你需要在别处搜索,这里甚至有两个答案。哦,看看这里。。。