Wrong mode when using PIL.blend with 'F' mode images? - python-imaging-library

The title says most of it: I'm trying to blend two images with mode F, that is 32-bit float pixel values. However, I get an error from PIL that says:
image has wrong mode
However, I have verified that both images are of mode F and cannot find any evidence that this shouldn't be possible. Is there some way to make this work, preferably without converting to a new image type?

I'm pretty sure, that – under the hood – Image.blend calls this implementation. The very first check there is:
/* Check arguments */
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
strcmp(imIn1->mode, "1") == 0 || imIn2->palette ||
strcmp(imIn2->mode, "1") == 0) {
return ImagingError_ModeError();
}
So, although not stated in the documentation, I'd guess, that Image.blend is only supported for uint8 image modes.

Related

How to throw an error during a parameter check without if-statements in Google-Earth-Engine?

I am working on a new version of the bfast monitor algorithm in Google Earth Engine. See the code of the original algorithm on Github.
The function bfastMonitor() takes user-defined parameters and applies some parameter checks before starting actual calculations. When the user-defined parameter settings are incompatible with the algorithm, an error should be raised.
During the parameter check, two types of if statements are made: statements that only check the parameter boundaries and raise an error at incompatible values, and statements that check and rewrite the contents of a parameter and raise an error at incompatible values. For the sake of the focus of this question, I will consider only the latter one.
Obviously, in a conventional coding paradigm, if-statements can be used to do this parameter check, however, using if-statements goes against the client-server model of GEE.
Consider the period parameter, which can only be 2,4,6,8, or 10. This parameter code used to index a list later in the code (line 459 on Github), where a period-value of 4 means that the list should be indexed at position 1, for instance.
Currently the implementation looks like this, using if-statements:
period = period||10
if (period == 2) {
period = 0;
} else if (period == 4){
period = 1;
}else if (period == 6){
period = 2;
}else if (period == 8){
period = 3;
}else if (period == 10){
period = 4;
}else {
alert("Error: for period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
}
Later on, the period parameter is used a form like this (from Github):
var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList[period];
The code could be rewritten easily to get rid of the if-statements, like this for instance:
var period = ee.Number(6);
var periodDict = ee.Dictionary({
'2':0,
'4':1,
'6':2,
'8':3,
'10':4,
});
var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList.get(periodDict.get(period.format()));
But then I don't know how to retain the opportunity to throw an error when the value for period is out of bounds.
How can I check the parameters of a function in Google Earth Engine and throw errors while avoiding if-statements?
There is nothing at all wrong with using a JavaScript if statement when it works. The advice you linked is about using ee.Algorithms.If which is unfortunately often inefficient — that's completely unrelated. The usual problem with a JavaScript if is when you're trying to use it on a server-side value that hasn't been computed yet.
But in your case, it looks like you want to validate a user-provided parameter. if is a perfectly fine way to do this.
I'll suggest one improvement: instead of using alert("error message");, use throw new Error:
throw new Error("For period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
This has two advantages:
It doesn't pop a dialog that the user must interact with before fixing the problem, but just results in an error message in the usual place, the Code Editor's Console.
It will stop the rest of the code from executing, which alert() doesn't.

GEN_NO_GENERATABLE_NOTIF

I want to choose index from list, so the element[index] complies my condition.
MyList[index].num==0
I tried the code bellow:
gen DescIdx2Choose keeping {
it < MyList.size();
MyList[it].num==0;//I tried a few way of read_only
};
How can I do it without using all_indices?
Thanks
Since you generating DescIdx2Choose then MyList will be input to the problem.
Therefore,
If seeking for the first index (if exists) then using random generation isn't required. Use the procedural code "first_index" as user3467290 suggested which is much more efficient:
var fidx := MyList.first_index(.num == 0);
if ( fidx != UNDEF ) {
DescIdx2Choose = fidx;
} else {
// error handling
};
If there are multiple indices and it is required to choose a random one, the most efficient way would be using "all_indices" as Thorsten suggested:
gen DescIdx2Choose keeping {
it in read_only( MyList.all_indices(.num == 0) );
};
The reason is the random generator doesn't need to read all possible values of "MyList.num" only a shorter list of valid indices.
This should do it, but MyList must fulfill the condition otherwise you get a contradiction. Pseudo-method first_index() is not bi-directional which is what we need here.
gen DescIdx2Choose keeping {
MyList.first_index(.num == 0) == it;
};
Maybe i missed something in the question, but If you always want the index of the first element that its num == 0, then why use constraints? can assign DescIdx2Choose == MyList.first_index(.num == 0).
To ensure that there is at least one such element, can constrain MyList.has(.num == 0).
Do you have additional constraints on DescIdx2Choose ?

libpd crashes with vlines~ in (libpd) clock_unset (?)

I have a iOS project developed with XCode that uses libpd to load a Pure Data patch. My project uses a mix of [osc~] and [phasor~] with modulated parameters (pitch, volume, etc). My app is in 64-bit as now required. I am using the latest version of Pure Data and libpd.
It crashes in one place. I have an [osc~] that has its pitch modulated by an envelope. When I change the value of the length of the envelope (= modulation rate) on a device, it randomly crashes during testing but always on the same line of libpd code. I thought it had to do with how fast the parameter was changed but no, it also happens when the parameter is slowly changed.
Here is below a (reduced) patch where the problem occurs. I have recently catched up with Pure Data. Any suggestions or corrections are welcome.
modulatedOscillator.pd
Here is a screenshot of the crash in XCode with the code sequence and the line of clock_unset that crashes.
(source: pdpatchrepo.info)
Full picture here.
I have done some printing and it crashes in this function:
void clock_unset(t_clock *x){
if (x->c_settime >= 0){
if (x == clock_setlist) clock_setlist = x->c_next;
else{
t_clock *x2 = clock_setlist;
while (x2->c_next != x) x2 = x2->c_next;
x2->c_next = x->c_next;
}
x->c_settime = -1;
}
}
On this line :
while (x2->c_next != x) x2 = x2->c_next;
With a printed value of : x2->c_next==NULL
Anyone has experienced something similar?
Thanks.

sws_scale screws up last pixel row in smaller x264 mp4 encoding

I am muxing pictures in the PIX_FMT_ARGB format into an mp4 video.
All of it works well, except that the last pixel row of the outgoing image is screwed up, in most cases the last row is completely black, sometimes there are other colors, it seems somehow dependant on the machine it runs on.
I am absolutely sure that the error must be in sws_scale, as I am saving the images before and after the scaling. The input images do not have the error, but after the sws_scale() I save the yuv image and the error is apparent.
Here is an example:
Original
Yuvfile (after sws_scale)
At the bottom of the Yuvfile, you will see the black row.
This is how I do the scaling (it is after the official ffmpeg examples, more or less):
static int sws_flags = SWS_FAST_BILINEAR | SWS_ACCURATE_RND;
if (img_convert_ctx == NULL)
{
img_convert_ctx = sws_getContext( srcWidth, srcHeight,
PIX_FMT_ARGB,
codecContext->width, codecContext->height,
codecContext->pix_fmt,
sws_flags, NULL, NULL, NULL );
if (img_convert_ctx == NULL)
{
av_log(c, AV_LOG_ERROR, "%s","Cannot initialize the conversion context\n");
exit(1);
}
}
fill_image(tmp_picture, pic, pic_size, frame_count, ptr->srcWidth, ptr->srcHeight );
sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize,
0, srcHeight, picture->data, picture->linesize);
I also tried a number of different SWS_ flags, but all yield the same result.
Could this be a bug in sws_scale or am I doing something wrong? I am using the latest version of the ffmpeg libraries.
The problem was this function:
fill_image(tmp_picture, pic, pic_size, frame_count, ptr->srcWidth, ptr->srcHeight );
It did not copy the input image to the tmp_picture correctly. Indeed skipped the last line.
Morale: Do not trust years-old functions :D
180 is not a multiple of 8, this could be the reason for the black row. Can you try scaling it to the nearest multiple of 8,say 184 or 192(multiple of 16)? Non h264 codecs need multiple of 8 as height.

Troubles with if-statement ||

I'm just working on a new porject an I'm working actually with simple coordinates:
if (locationOnJoystick.x > joystickArea.frame.size || locationOnJoystick.y > joystickArea.frame.size) {
But while running the code I get an ERROR:
error: invalid operands to binary > (have 'CGFloat' and 'CGSize')
Can anyone see the solution?!
Sincerly,
mavrick3.
locationOnJoystick.x is a CGFloat, while joystickArea.frame.size is a CGSize. They're different types, you cannot compare them.
I guess you should compare locationOnJoystick.x with the width of your joystickArea.frame.size (and the same with y and height):
if (locationOnJoystick.x > joystickArea.frame.size.width || locationOnJoystick.y > joystickArea.frame.size.height) {