write optical flow in .flo format to file as used in the Sintel dataset (Butler et al., 2012) flow: optical flow with shape height x width x 2 filepath: optical flow file path to be saved --- ".flo" file format used for optical flow evaluation Stores 2-band float image for
(flow, filepath)
| 134 | |
| 135 | |
| 136 | def writeFloFlow(flow, filepath): |
| 137 | """ |
| 138 | write optical flow in .flo format to file as used in the Sintel dataset (Butler et al., 2012) |
| 139 | flow: optical flow with shape height x width x 2 |
| 140 | filepath: optical flow file path to be saved |
| 141 | --- |
| 142 | ".flo" file format used for optical flow evaluation |
| 143 | |
| 144 | Stores 2-band float image for horizontal (u) and vertical (v) flow components. |
| 145 | Floats are stored in little-endian order. |
| 146 | A flow value is considered "unknown" if either |u| or |v| is greater than 1e9. |
| 147 | |
| 148 | bytes contents |
| 149 | |
| 150 | 0-3 tag: "PIEH" in ASCII, which in little endian happens to be the float 202021.25 |
| 151 | (just a sanity check that floats are represented correctly) |
| 152 | 4-7 width as an integer |
| 153 | 8-11 height as an integer |
| 154 | 12-end data (width*height*2*4 bytes total) |
| 155 | the float values for u and v, interleaved, in row order, i.e., |
| 156 | u[row0,col0], v[row0,col0], u[row0,col1], v[row0,col1], ... |
| 157 | """ |
| 158 | |
| 159 | height, width, nBands = flow.shape |
| 160 | |
| 161 | with open(filepath, "wb") as f: |
| 162 | if f is None: |
| 163 | raise IOError(f"write flo file {filepath}: file could not be opened") |
| 164 | |
| 165 | # write header |
| 166 | result = f.write(FLO_TAG_STRING.encode("ascii")) |
| 167 | result += f.write(struct.pack("i", width)) |
| 168 | result += f.write(struct.pack("i", height)) |
| 169 | if result != 12: |
| 170 | raise IOError(f"write flo file {filepath}: problem writing header") |
| 171 | |
| 172 | # write content |
| 173 | n = nBands * width |
| 174 | for i in range(height): |
| 175 | data = flow[i, :, :].flatten() |
| 176 | data[np.isnan(data)] = FLO_UNKNOWN_FLOW |
| 177 | result = f.write(struct.pack(f"{n}f", *data)) |
| 178 | if result != n * 4: |
| 179 | raise IOError(f"write flo file {filepath}: problem writing row {i}") |
| 180 | |
| 181 | |
| 182 | def readPngFlow(filepath): |