物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

コマンドでWord/Excel/PowerPoint のファイルをPDF/画像に変換する (Windows版)

方針としては、全部PDFに変換してから、画像に変換する。

PDFに変換するには、 LibreOffice を使う。使い方はここを見よ。 takuya-1st.hatenablog.jp

で終わったんだが、プログラムへのPathが変更されていた。

"C:\Program Files\LibreOffice\program\soffice.exe"

なので、実行すべきコマンドは

"C:\Program Files\LibreOffice\program\soffice.exe" --convert-to pdf --headless "C:\sample.pptx"

となるだろうか。スペースの入ったpathは""で囲むのを忘れないように。他のオプションは公式に詳細に書いてある。日本語にしてくれた方に感謝したい。

https://help.libreoffice.org/Common/Starting_the_Software_With_Parameters/jahttps://help.libreoffice.org/Common/Starting_the_Software_With_Parameters/ja

PDFを画像に変換する方法、pythonユーザーであれば python convert pdf to image で検索すればザクザク出てくる

from pdf2image import convert_from_path
images = convert_from_path(root + ".pdf")
i = 0
for image in images:
    images.save('{}_{:03d}.png'.format(root,i), 'png')
    i += 1

CERN ROOT6の.rootlogon.C の記述例 (プロジェクタで見えづらい色も調整済み)

root.cern.ch

ホームディレクトリに .rootlogon.C を置くと、自分のROOTの設定を毎回使えるので便利である。私が使ってるコードがあるので、サンプルとして公開してみる。Atlas styleを参考にした。

gitlab.com

黄緑色と空色はプロジェクタでの視認性が最悪であり、これも調整している。カラーユニバーサルデザイン推奨配色セットを使った。

f:id:onsanai:20190326010759p:plain
色の設定前(左)、設定後(右)

OpenCVを使った画像内のピーク検出プログラム

ピークの周波数によって、途中のBoxFilterとGaussianBlurのカーネルサイズは変えると良い。

背景の強度を求めて、有意度を求めるのがこのプログラムのミソである。

var size = new OpenCvSharp.Size(nbin, nbin);
Mat signal = Mat.Zeros(size, MatType.CV_32F);
var sig8U = new Mat(size, MatType.CV_8UC1);

//Fill
{
        float val = signal.Get<float>(iy, ix);
        signal.Set(iy, ix, val + (float)(1.0));
}

Mat bg = new Mat(size, MatType.CV_32F); // local average
Mat sub = new Mat(size, MatType.CV_32F); // signal - bg
Mat error = new Mat(size, MatType.CV_32F); // error
Mat sig = new Mat(size, MatType.CV_32F); // significance
Mat buf = new Mat(size, MatType.CV_32F); // buffer

Cv2.BoxFilter(signal, signal, -1, new OpenCvSharp.Size(3, 3), null, false); //3x3の膨張処理
Cv2.GaussianBlur(signal, bg, new OpenCvSharp.Size(15, 15), -1);
Cv2.Subtract(signal, bg, sub);

Cv2.Add(signal, bg, buf);
Cv2.Sqrt(buf, error);

Cv2.Add(error, 0.01, buf);
Cv2.Divide(sub, buf, sig);//0.01は0除算を避けるため

Cv2.ConvertScaleAbs(sig, sig8U, 255.0 / 5.0, 0);//>=5sigma = 255

Cv2.MinMaxLoc(sig, out double minval, out double maxval,
    out OpenCvSharp.Point minloc, out OpenCvSharp.Point maxloc);
cv::Size size = cv::Size(width, width);
cv::Mat signal = cv::Mat::zeros(size, CV_32F);
cv::Mat sig8U = cv::Mat(size, CV_8UC1);

//Fill
{
    signal.at<float>(cv::Point(dx + width / 2, dy + width / 2)) += 1;
}

cv::Mat bg = cv::Mat(size, CV_32F); // local average
cv::Mat sub = cv::Mat(size, CV_32F); // signal - bg
cv::Mat error = cv::Mat(size, CV_32F); // error
cv::Mat sig = cv::Mat(size, CV_32F); // significance
cv::Mat buf = cv::Mat(size, CV_32F); // buffer

cv::boxFilter(signal, signal, -1, cv::Size(3, 3), cv::Point(-1,-1), false); //3x3の膨張処理
cv::GaussianBlur(signal, bg, cv::Size(15, 15), -1);
cv::subtract(signal, bg, sub);

cv::add(signal, bg, buf);
cv::sqrt(buf, error);

cv::add(error, 0.01, buf);
cv::divide(sub, buf, sig);//0.01は0除算を避けるため

cv::convertScaleAbs(sig, sig8U, 255.0 / 5.0, 0);//>=5sigma = 255

double minval, maxval;
cv::Point minloc, maxloc;
cv::minMaxLoc(sig, &minval, &maxval,
    &minloc, &maxloc);

螺旋を描くためのC++ソースコード

uint64_t range = 1000;
int x = 0;
int y = 0;
uint64_t loop = 0;
uint64_t shift = 0;
for (uint64_t i = 1; i < range * range; i++) {
    std::cout<<x<<" "<<y<<" "<<i<<std::endl;
    if (i == (loop * 2 + 1) * (loop * 2 + 1)) {
        loop++;
        shift = 0;
        x++;
    }
    else {
        shift++;
        if (shift >= loop * 6) { x++; }
        else if (shift >= loop * 4) { y--; }
        else if (shift >= loop * 2) { x--; }
        else { y++; }
    }
}

素数だけ描くとこうなる。

f:id:onsanai:20190321180707p:plain
ウラムの螺旋

参照 ウラムの螺旋 - Wikipedia