Changes in the Motion plugin source code. ========================================= The following 2 new MotionMain class methods added. refine_global() refine_rotation() The following 3 new effect parameters added. Corresponding controls also added to the effect dialog. NOISE_LEVEL NOISE_ROTATION TWOPASS The following 3 new handy buttons added to the effect dialog. Get current - to set tracked frame number from the current cursor position Generate tracking file name - to suggest tracking file name based on the current asset name (like in the Motion51 plugin) Clear tracking file contents - to explicitly clear current tracking file contents (before clearing the contents is saved in the file with the suffix ".old") ================================================== Tracking translation (two pass tracking on). -------------------------------------------- The first pass is done as before. It will do only approximate search anyway, so subpixel search is skipped. The differences between translated and reference frame calculated for each match block position are compared to get the minimum and maximum difference. Then the new motion noise level parameter is applied to calculate noise level as percent between min and max difference. From the block positions whose differences are under noise level, that motion vector is taken which defines the smallest displacement from the best position found on the preceding cycle. The second pass is similar to the first one, with the following exceptions. As reference a temporary frame is used which is produced from that frame which was used in the first pass, but after applying translation and rotation calculated in the first pass. Searching is started not from Block X, Y coords set in the effect parameters, but from X = Y = 0 (the displacements found in the first pass have been compensated by pre-applying them to the reference frame). Translation search radius is reduced and placed symmetrically aroung zero coords. Subpixel search step is performed. Noise level is ignored. The displacements found in the second pass are added to the first ones to give the final refined translation vector. If two pass tracking is off, then translation search is done just as before, including subpixel search. If valid displacements have been loaded from the tracking file, then second pass is not called at all, calcuation skipped, and the loaded motion vector used as is. Improvement: the translation search grid is divided taking into account translation direction (horizontal/vertical/both), not to waste CPU time for unneeded repeated calculation for identical displacements (especially in subpixel search where cache is not used). Minor improvement: an additional translation vector defining zero displacement from the best position found in the preceding cycle is added to the set of tested positions. Such emphasizing the probably best position helps to utilize motion noise level efficiently. Minor improvement: the current translation search range is reduced on each cycle not twice, but to include +/- translation search grid cell size used in the preceding cycle around the best position found so far. So the translation search can be accelerated without loosing accuracy. Minor bugfix: in subpixel search the 2x2 pixel block was placed in such a way that the best pixel position was not in the 2x2 block center, but on its top left corner. Therefore not the whole area around the best pixel was checked with subpixel accuracy. This behavior is corrected now. Tracking rotation (two pass tracking on). ----------------------------------------- The first pass is done as before. It will do only approximate search anyway, so it is performed up to ~1 degree accuracy only. The differences between rotated and reference frame calculated for each angle are compared to get the minimum and maximum difference. Then the new rotation noise level parameter is applied to calculate noise level as percent between min and max difference. From the angles whose differences are under noise level, that angle is taken which has smallest absolute deviation from the best angle found on the preceding cycle. The second pass is similar to the first one, with the following exceptions. As reference a temporary frame is used which is produced from that frame which was used in the first pass, but after applying the complete translation and the rotation calculated in the first pass. Searching is started not from the rotation center which was set in the effect parameters, but from zero angle (the rotation found in the first pass has been compensated by pre-applying it to the reference frame). Rotation search radius is reduced and placed symmetrically aroung zero angle. Rotation search is performed with full accuracy. Noise level is ignored. The rotation angle found in the second pass is added to the first one to give the final refined rotation. If two pass tracking is off, then rotation search is done just as before. If valid angle has been loaded from the tracking file, then second pass is not called at all, calcuation skipped, and the loaded rotation angle used as is. ================================================== There exist an additional source of inaccuracy. Although the translation displacements are calculated to subpixel precision, the rotation pivot can be defined with entire pixel accuracy only. To compensate this discrepancy, the "previous" and "current" frames are interchanged in comparison: the current frame with applied translation and rotation is compared with the unmodified previous frame, to which the rotation pivot is assigned, and the obtained coords and angle are taken with opposite sign. For translation, it was in the old plugin already exactly so, but now such trick is used also for rotation. Minor improvement: some integer values which were calculated by integer division (and truncated), now are calculated in floating point followed by rounding. Minor improvement: if the tested rotation angle is exactly zero, a tiny angle is used instead for the difference calculation. It is necessary to trigger interpolation in the affine transformation engine, otherwise the difference calculation will produce a small spike in this place. Minor bugfix: the minimum angle limits (min_angle and MIN_ANGLE) were defined in radian, but then used in degrees instead. This bug lead to a lot of excess rotation calculations wasting CPU time. Minor improvement: an odd number of rotation search steps is used (for example, 17 instead of 16), in order to emphasize the angle in the symmetry center, so that it be always tested first. It helps to utilize rotation noise level efficiently, and also to get rid of spurious tiny rotation angles where actually there would be no rotation at all. Minor improvement: the current rotation range is reduced on each cycle not twice, but to include +/- rotation step size used in the preceding cycle. So the rotation search can be accelerated. Minor improvement/bugfix: the feature of adding loaded offset from tracked frame could be used before only for translation tracking, and only once during each instance of the motion effect (moreover, it did not work correctly). Now it is used also for rotation, and adding loaded offset can be requested any times in the same effect instance. Minor improvement/bugfix: the logics of clearing tracking file contents was doubtful. From other point, there may be a lot of diverse conditions under which this file is or is not to be cleared. Now clearing tracking file contents is done only manually (via a special pushputton in the plugin GUI), and never implicitly. The old tracking file contents is saved. But, as the suffix ".bak" is already in use in the caching system, another suffix ".old" is taken for this purpose. Minor improvement: the new GUI pushbutton "Generate tracking file name" can be used to suggest an automatic tracking file name based on the asset name (like in the Motion51 plugin). Minor bugfix: the .bak file left on disk after previous unsuccessful tracking could interfere with the new tracking pass. Now such file is always removed before the new one comes in use. Minor improvement: the new GUI pushbutton "Get current" reads the address of the current timeline cursor position and sets to it the value of the tracking frame number parameter.