firefly086 2023-03-19 22:35 采纳率: 50%
浏览 300
已结题

如何使用opencv套图(C++)?

需要解决的问题:

我需要将一张原图为jpg格式的图片,套入一个目标文件(文件为tiff格式)的第二个图层中。

注:套进去后,需要按这个图层(目标tiff文件的第二个图层)的形状进行裁剪,如图层是圆形,jpg图片套进来后就需要裁剪成圆形图片。

请问使用opencv c++如何实现该功能? (可以使用其它第三方如libtiff库)

  • 写回答

16条回答 默认 最新

  • 「已注销」 2023-03-19 22:43
    关注

    参考GPT和自己的思路:要实现将一张jpg格式的图片套入一个目标文件(文件为tiff格式)的第二个图层中并按照该图层的形状进行裁剪,可以按照以下步骤使用OpenCV和LibTIFF库:

    使用OpenCV加载原始图片,并获取其尺寸信息。例如,使用cv::imread函数加载jpg格式的图片,然后使用cv::Size函数获取它的宽和高:
    c++

    cv::Mat src = cv::imread("source.jpg");
    int width = src.cols;
    int height = src.rows;
    
    
    

    使用LibTIFF库加载目标文件,并获取其第二个图层的尺寸信息。例如,使用TIFFOpen函数打开tiff文件,使用TIFFSetDirectory函数选择第二个图层,然后使用TIFFGetField函数获取它的宽和高:

    TIFF* tif = TIFFOpen("target.tif", "r");
    TIFFSetDirectory(tif, 1); // select the second layer
    uint32_t tif_width, tif_height;
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tif_width);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tif_height);
    
    
    

    创建一个新的Mat对象,大小与目标文件的第二个图层相同,并将其填充为全黑。例如,使用cv::Mat的构造函数创建一个大小为tif_width x tif_height的全黑矩阵:

    cv::Mat dst(tif_height, tif_width, CV_8UC3, cv::Scalar(0, 0, 0));
    
    
    

    使用OpenCV的绘图函数将原始图片绘制到目标Mat对象上。这里需要考虑到图片套进去后需要按照目标图层的形状进行裁剪,可以使用cv::circle函数绘制一个与目标图层形状相同的掩码,然后使用cv::bitwise_and函数将原始图片和掩码进行按位与操作,从而裁剪原始图片。例如,使用cv::circle函数绘制一个圆形掩码,然后使用cv::bitwise_and函数将原始图片和掩码进行按位与操作:

    cv::Mat mask = cv::Mat::zeros(tif_height, tif_width, CV_8UC1);
    cv::Point center(tif_width / 2, tif_height / 2); // center of the mask
    int radius = std::min(tif_width, tif_height) / 2; // radius of the mask
    cv::circle(mask, center, radius, cv::Scalar(255, 255, 255), -1); // draw a white circle on the mask
    cv::Mat src_roi = src(cv::Rect(0, 0, std::min(width, tif_width), std::min(height, tif_height))); // get a subregion of the source image
    cv::Mat dst_roi = dst(cv::Rect(0, 0, std::min(width, tif_width), std::min(height, tif_height))); // get a subregion of the destination image
    src_roi.copyTo(dst_roi, mask); // copy the masked source image to the destination image
    
    
    

    使用LibTIFF库将目标Mat对象保存到tiff文件中。例如,使用TIFFOpen函数打开tiff文件,使用TIFFSetDirectory函数选择第二个图层,然后使用TIFFWriteEncodedStrip函数将目标Mat对象写入到tiff文件中:

    TIFFSetDirectory(tif, 1); // select the second layer
    TIFFWriteEncodedStrip(tif, 0, dst.data, dst.total() * dst.elemSize()); // write the destination image to the tiff file
    TIFFClose(tif); // close the tiff file
    
    
    

    完整代码如下:

    #include <opencv2/opencv.hpp>
    #include <tiffio.h>
    
    int main() {
        // load the source image
        cv::Mat src = cv::imread("source.jpg");
    
        // load the target tiff file and get the size of its second layer
        TIFF* tif = TIFFOpen("target.tif", "r");
        TIFFSetDirectory(tif, 1); // select the second layer
        uint32_t tif_width, tif_height;
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tif_width);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tif_height);
    
        // create a new image with the same size as the target tiff file's second layer and fill it with black
        cv::Mat dst(tif_height, tif_width, CV_8UC3, cv::Scalar(0, 0, 0));
    
        // create a mask with the same size as the target tiff file's second layer and draw a white circle on it
        cv::Mat mask = cv::Mat::zeros(tif_height, tif_width, CV_8UC1);
        cv::Point center(tif_width / 2, tif_height / 2); // center of the mask
        int radius = std::min(tif_width, tif_height) / 2; // radius of the mask
        cv::circle(mask, center, radius, cv::Scalar(255, 255, 255), -1); // draw a white circle on the mask
    
        // copy the masked source image to the destination image
        cv::Mat src_roi = src(cv::Rect(0, 0, std::min(src.cols, tif_width), std::min(src.rows, tif_height))); // get a subregion of the source image
        cv::Mat dst_roi = dst(cv::Rect(0, 0, std::min(src.cols, tif_width), std::min(src.rows, tif_height))); // get a subregion of the destination image
        src_roi.copyTo(dst_roi, mask); // copy the masked source image to the destination image
    
        // save the destination image to the target tiff file's second layer
        TIFFSetDirectory(tif, 1); // select the second layer
        TIFFWriteEncodedStrip(tif, 0, dst.data, dst.total() * dst.elemSize()); // write the destination image to the tiff file
        TIFFClose(tif); // close the tiff file
    
        return 0;
    }
    
    
    

    以上代码只是一个简单的示例,如果要在实际应用中使用,还需要考虑异常处理、内存管理等问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
    1人已打赏
查看更多回答(15条)

报告相同问题?

问题事件

  • 系统已结题 3月29日
  • 已采纳回答 3月21日
  • 创建了问题 3月19日

悬赏问题

  • ¥30 微信小程序请求失败,网页能正常带锁访问
  • ¥15 对语音信号进行变调时,间接改变时序从而实现语音变速,进而将变调与变速同时实现、参数合成法换为波形合成法
  • ¥30 德飞莱51单片机实现C4炸弹
  • ¥50 CrossLink-LIF-MD6000 型 FPGA 的 CMOS 转 MIPI D-PHY IP 核功能使用异常
  • ¥15 proteus控制16x16LED点阵显示屏的设计
  • ¥30 求会做山景bp1048b2程序的。做直播声卡用
  • ¥15 求数学建模论文问题指导
  • ¥15 51单片机与数码管实现电子琴
  • ¥15 h3.6m 人类行为预测论文复现
  • ¥50 wordpress项目注册报失败刷新后其实是成功状态,请求排查原因