こしあん
2019-10-05

OpenCVのsubtractについての小ネタ

Pocket
LINEで送る


OpenCVのsubtractと通常のNumpyの引き算の差が気になったのでメモ。実際に試してみました。

環境:Numpy:1.16.3, OpenCV:4.1.0

NumpyとOpenCVのsubtractの差

OpenCVとNumpy配列は密接に関係していて、新しい画像を作るときにnp.zerosなどのNumpy関数で初期化します。

ありがちなのがuint8型で初期化して、OpenCVで画像として扱うパターンです。uint8のNumpy配列を画像と見たてみます。普通にNumpyで引くケースと、OpenCVのsubtractで引くケースを比較します。

import cv2
import numpy as np

x = np.arange(27, dtype=np.uint8).reshape(3, 3, 3)
y = np.arange(27, dtype=np.uint8)[::-1].reshape(3, 3, 3)
print(x - y) # 普通に引き算
print(cv2.subtract(x, y)) # OpenCVのsubtract
# Numpyの引き算
[[[230 232 234]
  [236 238 240]
  [242 244 246]]

 [[248 250 252]
  [254   0   2]
  [  4   6   8]]

 [[ 10  12  14]
  [ 16  18  20]
  [ 22  24  26]]]
# OpenCVのsubtract
[[[ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [ 0  0  2]
  [ 4  6  8]]

 [[10 12 14]
  [16 18 20]
  [22 24 26]]]

Numpyの引き算はオーバーフローしているのに、OpenCVの引き算は0で底打ちされていてオーバーフローしていません

uint8以外ならどうか?

OpenCVのsubtractはただ単にマイナスの値を0と決め打ちしている疑惑が否定できないので、uint8からint32に変更して計算してみます。

x = np.arange(27, dtype=np.int32).reshape(3, 3, 3)
y = np.arange(27, dtype=np.int32)[::-1].reshape(3, 3, 3)
print(x - y)
print(cv2.subtract(x, y))
# Numpyの引き算
[[[-26 -24 -22]
  [-20 -18 -16]
  [-14 -12 -10]]

 [[ -8  -6  -4]
  [ -2   0   2]
  [  4   6   8]]

 [[ 10  12  14]
  [ 16  18  20]
  [ 22  24  26]]]
# OpenCVのsubtract
[[[-26 -24 -22]
  [-20 -18 -16]
  [-14 -12 -10]]

 [[ -8  -6  -4]
  [ -2   0   2]
  [  4   6   8]]

 [[ 10  12  14]
  [ 16  18  20]
  [ 22  24  26]]]

結果は同じになりました。つまり、OpenCVのsubtractはマイナスの値を0に丸めておらず、型に応じてオーバーフロー起こさないように調整しているだけのようです。

まとめ

OpenCVのsubtractとNumpyの引き算の差は、オーバーフローを引き起こすかどうか

Related Posts

KerasのModelCheckpointのsave_best_onlyは何を表すのか?... Kerasには「モデルの精度が良くなったときだけ係数を保存する」のに便利なModelCheckpointというクラスがあります。ただこのsave_best_onlyがいまいち公式の解説だとピンとこないので調べてみました。 ModelCheckpointとは? 公式ドキュメントより ke...
PyTorchで行列(テンソル)積としてConv2dを使う... PyTorchではmatmulの挙動が特殊なので、思った通りにテンソル積が取れないことがあります。この記事では、基本的な畳み込み演算である「Conv2D」を使い、Numpyのドット積相当の演算を行うという方法を解説します。 はじめに PyTorchの変態コーディング技術です。多分。 画像のテ...
Kerasで重みを共有しつつ、必要に応じて入力の位置を変える方法... Kerasで訓練させて、途中から新しく入力を作ってそこからの出力までの値を取りたいということがたまにあります。例えば、Variational Auto Encoderのサンプリングなんかそうです。このあまり書かれていないのでざっとですが整理しておきます。 こういうことをやりたい 言葉で書いても...
PyTorchでガウシアンピラミッド+ラプラシアンピラミッド(Gaussian/Laplacian ... Progressive-GANの論文で、SWD(Sliced Wasserstein Distance)が評価指標として出てきたので、その途中で必要になったガウシアンピラミッド、ラプラシアンピラミッドをPyTorchで実装してみました。これらのピラミッドはGAN関係なく、画像処理一般で使えるものです...
TensorFlow2.0で訓練の途中に学習率を変える方法... TensorFlow2.0で訓練の途中に学習率を変える方法を、Keras APIと訓練ループを自分で書くケースとで見ていきます。従来のKerasではLearning Rate Schedulerを使いましたが、TF2.0ではどうすればいいでしょうか? Keras APIの場合 従来どおりLea...
Pocket
Delicious にシェア

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です