New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GSoC 2022] new imread api with named parameters and outputarray #22431
base: 5.x
Are you sure you want to change the base?
Conversation
8995d78
to
934df25
Compare
modules/imgcodecs/src/loadsave.cpp
Outdated
|
||
// read the file signature | ||
String signature(maxlen, ' '); | ||
maxlen = fread( (void*)signature.c_str(), 1, maxlen, f ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c_str() returns const char*
for a reason. Casting and writing to that pointer should be avoided (it could be a shadow copy).
Mutable std::vector<uint8_t>
or cv::AutoBuffer<int8_t>
should be used instead (perhaps including .checkSignature()
)
enum ImreadError { | ||
IMREAD_OK = 0, | ||
IMREAD_ERROR_FILE_NOT_FOUND, | ||
IMREAD_ERROR_UNRECOGNIZED_FORMAT, | ||
IMREAD_ERROR_SIZE_LIMIT_EXCEEDED, | ||
IMREAD_ERROR_INVALID_HEADER, | ||
IMREAD_ERROR_INVALID_DATA, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation is 4 spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other enum definitions in the same file have 7 spaces. Should i keep 7 spaces or change to 4 spaces?
modules/imgcodecs/src/loadsave.cpp
Outdated
if( flags & IMREAD_REDUCED_GRAYSCALE_2 ) | ||
scale_denom = 2; | ||
else if( flags & IMREAD_REDUCED_GRAYSCALE_4 ) | ||
scale_denom = 4; | ||
else if( flags & IMREAD_REDUCED_GRAYSCALE_8 ) | ||
scale_denom = 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semantically this should be a direct field of ImreadParams
.
Otherwise there is unresolved mess between flags
and ImreadParams
in designed API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alalek Do you mean that i should split flags into scale_denom and loadGdal variable and put it inside ImreadParams?
} | ||
if (!success) | ||
{ | ||
image.release(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have doubts about image.release();
@@ -160,6 +167,32 @@ enum ImwritePAMFlags { | |||
IMWRITE_PAM_FORMAT_RGB_ALPHA = 5 | |||
}; | |||
|
|||
|
|||
enum ImreadError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ImreadStatus
should be better, because some status are not errors.
modules/imgcodecs/src/loadsave.cpp
Outdated
#endif | ||
|
||
/// if no decoder was found, return nothing. | ||
if( !decoder && error != IMREAD_OK){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error
is not defined for GDAL case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be ||
, not &&
. I have updated this one too.
def test_imread2(self): | ||
path = self.find_file('python/images/baboon.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) | ||
ret, img = cv.imread2(path, maxSize = (512, 512)) | ||
self.assertEqual(0, ret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return codes should be available in python too. magic numbers look very strange.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are available. It was my bad to not use it :). Thanks for pointing out.
modules/imgcodecs/src/loadsave.cpp
Outdated
@@ -257,6 +257,46 @@ static ImageDecoder findDecoder( const String& filename ) { | |||
return ImageDecoder(); | |||
} | |||
|
|||
static ImageDecoder findDecoder( const std::string& filename, ImreadError& error ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function duplicates the original function, but adds more statuses. The old function should re-call the new one to not duplicate code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
* | ||
*/ | ||
static ImreadError | ||
imread_2( String const& filename, OutputArray image, ImreadParams params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function duplicates the original function, but adds more statuses. The old function should re-call the new one to not duplicate code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will work on this one. Since I have separate flags
variable into flags
and scaleDenom
, I need to find a way to merge them back together.
I think Previous code is : if (!image_data.empty() && (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED )
{
ApplyExifOrientation(decoder->getExifTag(ORIENTATION), image_data);
} It would be better if if (!image_data.empty() && ignore_orientation && flags != IMREAD_UNCHANGED )
{
ApplyExifOrientation(decoder->getExifTag(ORIENTATION), image_data);
} Where ignore_orientation is a boolean variable. |
This proposed new imread api based on named parameters.
There are a few things that needs to be discussed. I have not seen
enum class
usage in openCV. Hence i prepared this pull request using plain enum. Imo, enum classes are better to express intention hence should be favor when usable. I propose to useIt is more readable without
IMREAD_ERROR_
prefix. And user can safely check error type withImreadError::xxxx
without implicit conversion.The other thing is i created a new
findDecoder
method. This is kinda duplicate function. I could implement it viaThis is fine and works with the existing api, however it adds 2 extra if check. So if user reads thousand of images and does not use the new api, it adds 2 extra if check. I am not sure if this is ok or not.
Other than that, C++20 users can use designated initializers. Aggregate initialization does not permit default member initialization in C++11, this restriction removed at C++14.
In C++11 :
This code sample does not compile, but it compiles with C++14 version
Sample usage :
================================================================================================
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.