• LIBTIFF存储代码,存图、拼图


    首先准备几张图片

    我要把这几张图片拼成一张大图,拼接效果如下所示:

    继续往下看。

    一 准备图片

     1     std::vector<std::string> fileNames;
     2     fileNames.push_back("./Scan-Compare/1.jpg");
     3     fileNames.push_back("./Scan-Compare/2.jpg");
     4     fileNames.push_back("./Scan-Compare/3.jpg");
     5     fileNames.push_back("./Scan-Compare/4.jpg");
     6     fileNames.push_back("./Scan-Compare/5.jpg");
     7     fileNames.push_back("./Scan-Compare/6.jpg");
     8     std::vector<cv::Mat> mats;
     9     CTileTiff tiff("D:/1.tiff");
    10  
    11     for (int i = 0; i < fileNames.size(); i++)
    12     {
    13         cv::Mat img = cv::imread(fileNames[i]);
    14         cv::Mat dst;
    15         resize(img, dst, Size(4096, 4096), 0.0, 0.0);
    16         //cv::imshow("dst", dst);
    17         cv::cvtColor(dst, dst, CV_BGR2RGB);
    18         mats.push_back(dst);
    19     }

    二.设置TIFF的文件信息

    1 bool CTileTiff::SetTileInfo(int nTileW, int nTileH, int nLayer,int nHeight,int nWidth)
    2 {
    3     m_nTileWidth = nTileW;
    4     m_nTileHeight = nTileH;
    5     m_nLayers = nLayer;
    6     m_nWidth = nWidth;
    7     m_nHeight = nHeight;
    8 }

    三.存储每一张图片

     1 bool CTileTiff::SaveImage(cv::Mat &img, const int nLeft, const int nTop,
     2     const int nRight, const int nBottom)
     3 {
     4     int nX = nLeft, nY = nTop;
     5  
     6     //int nWidth = nRight - nX, nHeight = nBottom - nY;
     7     const int nRows = img.rows / m_nTileHeight;
     8     const int nCols = img.cols / m_nTileWidth;
     9     cout << "nRows,nCols:" << nRows << "," << nCols << endl;
    10  
    11     const int nPitch = (nRight - nLeft) * 3;
    12     const int nLayerID = 0;
    13  
    14     for (int i = 0; i < nRows; ++i)
    15     {
    16         const int nT = nY + i * m_nTileHeight;
    17         const int nB = nT + m_nTileWidth;
    18         for (int j = 0; j < nCols; ++j)
    19         {
    20             const int nL = nX + j * m_nTileWidth;
    21             const int nR = nL + m_nTileWidth;
    22             cout << nT << "," << nL  << endl;
    23  
    24             cv::Rect rect(j * m_nTileWidth, i * m_nTileHeight, m_nTileWidth, m_nTileHeight);
    25  
    26             cv::Mat roi = img(rect).clone();
    27  
    28  
    29             bool bOk = saveTile(roi, nL, nT, nR, nB, nLayerID);
    30             if (!bOk)
    31             {
    32                 continue;
    33             }
    34         }
    35     }
    36 //这里是为了下采样,按金字塔格式存储
    37     int nSubW = nCols, nSubH = nRows;
    38     int nSubLayer = nLayerID;
    39     while (true)
    40     {
    41         nSubW /= 2;
    42         nSubH /= 2;
    43         nSubLayer++;
    44         if (1 > nSubW || 1 > nSubH)
    45         {
    46             break;
    47         }
    48  
    49         const int nScale = 1 << nSubLayer;
    50         for (int i = 0; i < nSubH; ++i)
    51         {
    52             const int nT = nY + i * m_nTileWidth * nScale;
    53             const int nB = nT + m_nTileHeight * nScale;
    54             for (int j = 0; j < nSubW; ++j)
    55             {
    56                 const int nL = nX + j * m_nTileWidth * nScale;
    57                 const int nR = nL + m_nTileWidth * nScale;
    58        
    59  
    60  
    61                 cv::Rect rect(nL - nX, nT - nY, m_nTileWidth * nScale, m_nTileHeight * nScale);
    62  
    63                 cv::Mat roi = img(rect).clone();
    64  
    65                 cv::Mat resized;
    66  
    67                 ResizeImg(roi.data,
    68                     resized.data, m_nTileWidth * nScale, m_nTileHeight * nScale, 3, nPitch, m_nTileWidth, m_nTileHeight,
    69                     3, m_nTileWidth*3);
    70  
    71                 
    72                 bool bOk = saveTile(resized, nL, nT, nR, nB, nSubLayer);
    73                 if (!bOk)
    74                 {
    75                     continue;
    76                 }
    77             }
    78         }
    79     }
    80     
    81  
    82     return true;
    83 }

    四. 存储每一个tile

     1 bool CTileTiff::saveTile(cv::Mat& roi, const int nL, const int nT,const int nR, const int nB, const int nLayer)
     2 {
     3     if (roi.empty())
     4     {
     5         return false;
     6     }
     7     const int nWidth = nR - nL;
     8     const int nHeight = nB - nT;
     9     int nLength = 0;
    10  
    11     cout << nL << "," << nT << "," << nR << "," << nB << endl;
    12  
    13     try
    14     {
    15         TIFFSetDirectory(m_pFile, nLayer);
    16         TIFFSetField(m_pFile, TIFFTAG_IMAGEWIDTH, m_nWidth/(nLayer+1));
    17         TIFFSetField(m_pFile, TIFFTAG_IMAGELENGTH, m_nHeight/(nLayer + 1));
    18         TIFFSetField(m_pFile, TIFFTAG_TILEWIDTH, m_nTileWidth);
    19         TIFFSetField(m_pFile, TIFFTAG_TILELENGTH, m_nTileHeight);
    20         TIFFSetField(m_pFile, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
    21         TIFFSetField(m_pFile, TIFFTAG_BITSPERSAMPLE, 8);
    22         TIFFSetField(m_pFile, TIFFTAG_SAMPLESPERPIXEL, 3);
    23         TIFFSetField(m_pFile, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    24         TIFFSetField(m_pFile, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
    25         TIFFSetField(m_pFile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
    26         int nJpegQuality = 60;
    27         TIFFSetField(m_pFile, TIFFTAG_JPEGQUALITY, nJpegQuality);
    28  
    29         //根据需要设置分辨率
    30         /*if (nLayer == 0)
    31         {
    32             float fPixelSize = 0.00068f;
    33             int nScale = 20;
    34             fPixelSize = fPixelSize * 100 / max(1, nScale);
    35             TIFFSetField(m_pFile, TIFFTAG_XRESOLUTION, 1.0 / (fPixelSize / 10));
    36             TIFFSetField(m_pFile, TIFFTAG_YRESOLUTION, 1.0 / (fPixelSize / 10));
    37             TIFFSetField(m_pFile, TIFFTAG_RESOLUTIONUNIT, 3);
    38         }*/
    39  
    40  
    41         // save tile information
    42         const int nTileRow = nT / m_nTileHeight;
    43         const int nTileCol = nL / m_nTileWidth;
    44         int tiffIndex = nTileRow * (m_nWidth / (nLayer+1)/m_nTileWidth) + nTileCol;
    45         cout << "tiffIndex:" << tiffIndex << "," << nTileRow << "," << nTileCol << ","   << endl;
    46  
    47         TIFFWriteEncodedTile(m_pFile, tiffIndex, (void*)roi.data, m_nTileWidth * m_nTileHeight * 3);
    48  
    49         TIFFWriteDirectory(m_pFile);
    50  
    51         
    52     }
    53     catch (const std::exception& e)
    54     {
    55         //LOG_E("write tiff error:%s", e.what());
    56     }
    57  
    58     return true;
    59 }

    五.简单的存储DEMO

     1     int nWidth = mats[0].cols;
     2     int nHeight = mats[0].rows;
     3     tiff.SetTileInfo(256, 256, 1, nHeight*2, nWidth*3);
     4     
     5     //第一行. 这样是为了demo 看起来容易理解,真正开发的时候你至少得用循环吧。。。
     6     tiff.SaveImage(mats[0], 0, 0, nWidth, nHeight);
     7     tiff.SaveImage(mats[1], nWidth, 0, nWidth * 2, nHeight);
     8     tiff.SaveImage(mats[2], nWidth*2, 0, nWidth * 3, nHeight);
     9     //第二行
    10     tiff.SaveImage(mats[3], 0, nHeight, nWidth, nHeight*2);
    11     tiff.SaveImage(mats[4], nWidth, nHeight, nWidth * 2, nHeight * 2);
    12     tiff.SaveImage(mats[5], nWidth * 2, nHeight, nWidth * 3, nHeight * 3);
  • 相关阅读:
    Jedis入门
    redis的安装
    redis概述
    020 SpringMVC返回Json
    019 数据绑定流程分析(校验)
    018 数据绑定流程分析(包括数据转换与格式化)
    maven添加插件,与maven打包
    定制库到maven库
    maven仓库
    Maven启动代理访问
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13704500.html
Copyright © 2020-2023  润新知