2

I have a C++ program running some OpenCV processing on 4096x4096 JPEG2000 images that have geographical metadata. I don't want to modify the original, the results of my image manipulations are stored in a new image file. Since my resulting image is missing the data, I have implemented a copy method in my program using CreateCopy() to copy the source image data into the new image. On a 216kB image it takes 97sec to copy!

I have tried GDALSetCacheMax(200) and it seems to be worse.

I can't understand why such a small piece of metadata takes longer than even my OpenCV image processing algorithms! Please help!

Here is a sample GDALINFO output for a correct image. If I don't use CreateCopy, then my new image is missing the coordinate system, and the corner coordinates are just the pixel dimensions.

Driver: JP2OpenJPEG/JPEG-2000 driver based on OpenJPEG library
Files: <filename>.jp2
Size is 4096, 4096
Coordinate System is:
GEOGCS["WGS 84",
    DATUM["WGS_1984",
        SPHEROID["WGS 84",6378137,298.257223563,
            AUTHORITY["EPSG","7030"]],
        AUTHORITY["EPSG","6326"]],
    PRIMEM["Greenwich",0],
    UNIT["degree",0.0174532925199433],
    AUTHORITY["EPSG","4326"]]
Origin = (-97.025756835937500,32.398681640625000)
Pixel Size = (0.000001341104507,-0.000001341104507)
Image Structure Metadata:
  INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left  ( -97.0257568,  32.3986816) ( 97d 1'32.72"W, 32d23'55.25"N)
Lower Left  ( -97.0257568,  32.3931885) ( 97d 1'32.72"W, 32d23'35.48"N)
Upper Right ( -97.0202637,  32.3986816) ( 97d 1'12.95"W, 32d23'55.25"N)
Lower Right ( -97.0202637,  32.3931885) ( 97d 1'12.95"W, 32d23'35.48"N)
Center      ( -97.0230103,  32.3959351) ( 97d 1'22.84"W, 32d23'45.37"N)
Band 1 Block=1024x1024 Type=Byte, ColorInterp=Red
  Overviews: 2048x2048, 1024x1024, 512x512, 256x256
  Overviews: arbitrary
Band 2 Block=1024x1024 Type=Byte, ColorInterp=Green
  Overviews: 2048x2048, 1024x1024, 512x512, 256x256
  Overviews: arbitrary
Band 3 Block=1024x1024 Type=Byte, ColorInterp=Blue
  Overviews: 2048x2048, 1024x1024, 512x512, 256x256
  Overviews: arbitrary

GDAL code:

//GDAL Data
const char *pszFormat = "JPEG2000";
GDALDriver *poDriver;
GDALDataset *srcDataset;
GDALDataset *dstDataset;
GDALAllRegister();
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);

//Get Source metadata
srcDataset = (GDALDataset *) GDALOpen(imagePath, GA_ReadOnly);

//Create new image data
imwrite(maskPath, dst);

//Write metadata to new image
dstDataset = poDriver->CreateCopy(maskPath, srcDataset, false, NULL, NULL, NULL);
if(dstDataset != NULL)
{
    GDALClose((GDALDatasetH)dstDataset);
}
10
  • Please edit your question to provide more detail about the images, such as gdalinfo output for the source and new images.
    – user2856
    Apr 13, 2015 at 22:30
  • A bit of code might help too, is this GDAL in python, C#, VB.net, C++, Java, Ruby, Perl? What driver are you copying to? Is it copying JP2 to JP2 (which one? OpenJPEG, ECW, Jasper, Kakadu)? How many bands does the image have? Is it Grey, RGB, RGBA, RGBI or multispectral? What compression settings are you using (Lossless or by value)... Perhaps GeoTiff or HFA driver might work better. Apr 13, 2015 at 23:15
  • CreateCopy should for sure be faster but perhaps you are not doing the right thing because it can be possible to add just the metadata without rewriting the image data. See the append_gmljp2_box.py example at site even.rouault.free.fr.
    – user30184
    Apr 14, 2015 at 5:17
  • I have edited the question and added more details. @user30184 - Shouldn't CreateCopy be moving the metadata only? It definitely does not change the underlying image. In my C++ program I create the new image file first, then call CreateCopy() pointing to the same image file as the destination. I get the correct result, but it takes forever. Apr 14, 2015 at 13:47
  • @Luke hopefully this detail helps. Apr 14, 2015 at 13:59

2 Answers 2

1

This problem was solved by mimicking the behavior of gdalcopyproj.py; but it required updating to the "not yet stable" GDAL2.0 code set.

0

Late to the party, but:
why don't you just copy the unopened file, either using the tools provided by your operating system, e.g.

copy <path/to/myfile.jp2> <path/to/workingcopy.jp2>

or using the C++ filesystem library

std::filesystem::copy_file(<path/to/myfile.jp2>, <path/to/workingcopy.jp2>)

and then open and edit it with GDAL/OpenCV?

That copy operation will not actually open and decode the file, so it ought to be done in a few seconds at most.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.