デジタル採点」カテゴリーアーカイブ

塗りつぶさないマークシート

「塗りつぶす」方式でなく、より簡易な「線を引く」方式でマークするシートの例。

複数マーク可能なマークシート(選択肢は0~99 に対応)を作成したら、マークする時間そのものを短縮する必要性を痛感。今回は「よりはやく」・「よりカンタン」にマーク可能なシート作りに挑戦。

【もくじ】

1.もっとはやくマークできないか?
2.凡例として線でマークして違和感のないカタチは?
3.「線」マークの読み取りテスト
4.まとめ
5.お願いとお断り

1.もっとはやくマークできないか?

設問数が100ある試験で、複数マークを可とした場合、受験者は制限時間内に最大で200近いマークを塗りつぶさなくてはならない。制限時間が50分の試験で、190個マークするとして、1個2秒でマークした場合、マークするのに必要な時間は380秒、すなわち6分20秒となる。1個3秒でマークした場合の必要時間は、なんと9分30秒。制限時間の1/5がマークするためだけに使われてしまう。

採点者がラクをするのに、無理やり付き合わされる受験者の不満が爆発するのが見えるような気がして、小心者の筆者は「マークするために必要な時間を短縮する」にはどうしたらいいか、必死で考えた。

これまでに使用してきたマークシートのマークは、すべて選択肢の番号を縦長だ円で囲んだもの。

これまでに使用してきたマークシート


実際には、テストしてみると、次のようにマークしても読み取りパラメータの設定次第で十分読み取り可能なのだが・・・

こんなマークでも、実際には読み取りが可能。


しかし、受験者の心理として、選択肢が縦長だ円で囲まれていれば、だ円内を塗りつぶしたくなるもの。塗りつぶさず、「線」でマークしてもらうには、「線」でマークしたくなる形状にマークシートを改良しなければならない。

最初に考えたのは、「選択肢の番号を縦長四角形で囲む」という方法。

たとえば、こんな感じ


ただ、これだと、凡例で次のようにマーク方法を示してあっても・・・

どちらかと言えば、これはむしろ「悪いマーク」の例


真面目な受験者であれば、あるほど・・・

枠内を塗りつぶさなくてはいけないと考えるのが自然。


かといって、次のようにすると、デザインとして美しくない気がするし、四角形の幅が狭まったたけで「塗りつぶし」たくなる気持ちは同じ。

塗りつぶし面積が減少しただけ?


そんな、こんな理由から縦長四角形で選択肢の番号を囲むというアイデアは見送ることに決定。

2.凡例として線でマークして違和感のないカタチは?

では、凡例として線でマークしてあっても受験者に違和感を与えないマークとは、どんなマークか?

思いついたのは「囲みのない」マーク。これなら・・・

凡例として「線」が使えるし、塗りつぶしたくても塗りつぶす枠がない!


ただ、これだとマークシートっぽくない気が・・・。

マークシートらしくするために一工夫した結果・・・

[ ] 記号で数字の上下を囲んでみた


これならマークの凡例として、「線」が使えるのではあるまいか?


で、出来上がったのが、このマークシート。

複数マーク可能な「線」でマークするシート(設問数は100設問まで)


このマークシートは、次のリンク先からダウンロードすることができます。

3.「線」マークの読み取りテスト

例え、「線」であっても、これまでの経験からまず間違いなくマークの読み取りには成功すると思ったが、「やっぱりできませんでした!」では使ってくださる方に申し訳がたたないので、念のためテストを実行。

読み取り結果を確認しやすいように、設問番号にマークした次のようなマークシートを作成。やっぱり「線」で引く方が、「塗りつぶし」より遥かにラクであることを実感。これなら1設問に対し2か所マークしても「塗りつぶす」より、全然はやい!!

筆記用具は、シャープペンシルを使用。
芯は、HBの0.5mm。
用紙はホームセンターなどで普通に販売されている白色度の高いコピー用紙を使用。
(普段マークシートの印刷に使用している再生紙より、白色度が高いもの)


MS_Reader.exe を起動し、パラメータ設定はデフォルトのまま、読み取りテストを実行。

スキャナーの解像度は200dpiに設定。
カラー画像としてスキャン。
テスト1回目で、全てのマークの読み取りに成功!


間違いなく読めると思ってはいたけれど、ちょっと(あれっ?)って思ったのは、デフォルトパラメータの設定のまま、テスト第1回目で、全てのマークを正しく読み取ることに成功したこと。

実は、今回、実験で使用した用紙とは異なる、白色度が70%程度の再生コピー用紙を用いて予備的に実験した際は、閾値のパラメータをデフォルト設定より1~3程度大きく設定しないと読み取れないマークがあったのだ。今回、実験したものと「線」そのものの濃さや太さが厳密には異なるから正確なことは言えないが、白色度が高い用紙の方が二値化の際に有利なのだろうか?

・・・ということで、今回の実験では何も問題が起きなかったので、その前に行った白色度が70%程度の再生コピー用紙を使って行った予備実験で発見できた問題と対応方法を紹介。

(これは当Blogの過去記事「100選択肢対応マークシートを使用した試験の実施方法」に書いたものの再録です)

【重要】二値化閾値の修正方法(20240707追加)

マークが「うすい」場合、これを正しく読み取ることができず、「空欄」と判定して「999」と表示される場合があります。同じ理由で、複数マークされた解答欄の「1の位」が読めなかった場合も、読み取り判定は「マークの状態に問題あり」となり、「999」と表示されます。

これらの場合は、この後、実行する「読み取り結果のチェック」時に、該当箇所の解答欄が赤枠で囲まれて表示されますので、マークの状態をヒトの眼で確認し、読み取り結果を修正できます。

最も困るのが、複数マークされた解答欄の「10の位」のマークは薄くて読めなかったが、「1の位」のマークの読み取りには成功している場合です。この場合は正しく読み取れた「1の位」のマークが読み取り結果として表示されてしまいます。大変申し訳ないのですが、MS_Reader.exe のチェックプログラムは、この誤読を見つけることができません!!(これは原理的な問題なので、チェックする方法がありません)

この事故を防ぐには、事前に読み取りテストを十分に行って、読み取りパラメータを調整するしか方法がありません。具体的には、最もマークの濃度が薄い受験者のマークシートが正しく読めるようになるまで、閾値の値を1ずつ大きくして読み取りテストを実行します。筆者の行ったテストでは、デフォルト設定の閾値(180)では正しく読めなかったマークも、閾値を大きくすれば読めるようになりました。

「塗りつぶす」方式でなく、より簡易な「線を引く」方式でマークするシートを用いて行った読み取りテストの例

「64」と読むべき箇所の「10の位」を「空欄」と判定、「1の位」は正しく読めた場合、プログラムは読み取り結果を「4」と表示してしまう。


閾値を「1」大きくすると・・・

正しく読めるようになりました。


ごく薄いマークも正しく読めるようになるまで、この操作をくり返します。筆者の行ったテストでは、閾値を1ずつ大きくすることで、指示通り普通の濃さ(マーク箇所の数字が読めなくなる濃さ)でマークされたシートであれば、最終的にすべてのマークを正しく読めるようになりました(上記のマークシートを使用して行った実験では、最終的にすべてのマークを正しく読めた段階で、二値化の閾値の値は「184」でした。なお、このマークシートは後日公開する予定です)。

ただ、あまりにもマークの濃さが薄い場合は「原理的に読めません」ので、「対応不可」としてヒトの眼で読むしかないと思います・・・。

そのような事態にならないよう、予め受験者に対し「薄いマークは読み取れない」旨の注意を徹底しておく必要があります。マークシートを用いた試験では、これが最も重要なことかもしれません。

4.まとめ

(1)複数マーク可能なマークシートを使う場合は、「線」でマークできるようにする。
(2)マークシートを印刷する用紙は、白色度の高いものがよい?カモ
(3)マークシートは「濃く」マークするよう、予め注意を徹底する。

追記_20240709

【注意】複数マーク可能なマークシートでは、音声読み上げ機能は正しく動作しません!

5.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

100選択肢対応マークシートを使用した試験の実施方法

自作マークシートリーダーのプログラムを書き替え、大語群(使用できる選択肢の番号は 0~99)の使用に対応したマークシートを Excel で作成した。

今回は、このマークシートを用いた試験を実施する方法です。

【もくじ】

1.事前の準備と受験者への注意事項
2.スキャナーでマークシートをスキャンしてJpeg画像に変換
3.指定のフォルダ内にフォルダを作成してスキャンした画像をコピー
4.採点専用画像に変換
5.テンプレートとして登録
6.マーク読み取りを実行
7.マーク読み取り結果のチェック
8.CSV形式で出力
9.採点結果通知シートの作成方法
10.お願いとお断り

100選択肢に対応したマークシートリーダーです。

1.事前の準備と受験者への注意事項

(1)マークシートの印刷

プログラムに添付した R25C04D19.xlsx をダブルクリックして開き、必要な枚数をインクジェットプリンタで印刷します。印刷設定はA4・横に設定済みです。用紙はホームセンター等で購入できるコピー用紙を使用してください(読み取りパラメータの設定とマークの読み取りテストは再生コピー用紙を使用して行っています)。マークや罫線枠が設定よりも濃く印刷される輪転機での印刷はお止めください。

100選択肢(0~99)に対応した、複数選択可能なマークシート 「R25C04D19.xlsx」


(2)受験者への注意事項

試験を実施する前にHB以上の濃さの鉛筆とプラスチック消しゴムを用意するよう、受験者全員に連絡してください。可能であれば、シャープペンシルの使用は禁止した方がよいと思います。

問題冊子の表紙には、次の注意事項を印刷してください。


上記注意事項のサンプルをダウンロードできます。

2.スキャナーでマークシートをスキャンしてJpeg画像に変換

(1)スキャンの準備

解答用紙(マークシート)をスキャナーでスキャンする前に、解答用紙が裏返しだったり、逆さまになっていないかどうか等の確認に加え、次のことを必ず実行してください。

・解答用紙に付着している消しゴムの屑をしっかり落とす。
・受験番号(出席番号)が昇順になるよう、解答用紙の並び順を2回以上確認する。
・欠席者がいる場合は、未使用の解答用紙を該当箇所に挿入する。

(2)スキャナーの設定

解答用紙(マークシート)をスキャンする際の読み取り解像度は 200dpi で十分です(解像度を大きく設定しても、MS_Reader.exe での利用に関する限り、メリットは何一つありません)。また、画質は「カラー」を指定し、出力先はPDFファイルではなく、Jpeg画像を指定してください。

3.指定のフォルダ内にフォルダを作成してスキャンした画像をコピー

スキャンしたJpeg画像は、MS_Reader.exeと同じ階層にあるScanDataフォルダ内に適切な名称のフォルダを作成し、そこに保存してください。

【利用できるフォルダ構造】

〇:ScanData¥1年A組

【利用できないフォルダ構造】

×:ScanData¥1年¥A組

ScanData フォルダ内に新規にフォルダを作成し、さらにそのフォルダ内に新規にフォルダを作成して、そこにスキャンした Jpeg 画像を保存するような使い方は出来ません。ご注意ください。

4.採点専用画像に変換

ScanData フォルダ内に新規に作成したフォルダにスキャンしたJpeg画像が用意できたら、次にこの画像をマークシートリーダーで読むための専用画像に変換します。その理由はいくつかありますが、主なものは次の三つです。

(1)読み取り原本は、オリジナル状態のまま残しておく。
(2)マーク読み取り後に人の眼でチェックする際、作業しやすい大きさに整える。
(3)Loop 処理するため、画像の名称を統一し、1から始まる連番の番号を付ける。

具体的な方法は次の通りです。

(1)ダウンロードした Zip ファイルを展開したフォルダ内にある MS_Reader を起動します。

上のアイコンをダブルクリックして起動します。


(2)画面左上のメニューの「1 画像変換」をクリックします。


(3)表示されたサブメニューの「専用画像を作成」をクリックします。


(4)次のフォームが表示されます。画面右上の「選択」ボタンをクリックします。


(5)ScanDataフォルダの内容が表示されます。マークの読み取り処理を行いたいJpeg画像を保存したフォルダをクリックして選択します。選択したフォルダ名が下の「Folder」部分に表示されていることを確認して「OK」をクリックしてください。

【重要】選択するのは「フォルダ」で、「ファイル」ではありません!

Folder部分に、選択したフォルダ名が表示されます。


(6)画面は次のようになります。画面の中央左に表示されたサムネイル画像を参考にして、画像の回転の有無及び回転方向を選択し、続けて、リサイズの有無と縮小率を指定します。読み取り解像度が200 dpi ・A4横形式で、マークシートの列が4列ある場合は、「80%に縮小」してください。


(7)変換処理を行った画像データの出力先(書き出し先)フォルダを指定します。「参照」ボタンをクリックしてください。再びフォルダの選択ダイアログが表示されます。


(8)プログラムは、(5)で指定されたScanDataフォルダ内のフォルダと同じ名前のフォルダをProcDataフォルダ内に自動的に作成します。フォルダをクリックして選択し(下のFolder部分に選択したフォルダ名が表示されたことを確認)、OKをクリックしてください。

【参考】ProcData は、Processed(加工済み)の意味です。短くしすぎカモですが・・・


(9)ProcDataに続くPathを確認し、「変換実行」ボタンをクリックします。

〇:ProcData¥(自動的に作成されたスキャンした画像を保存したフォルダと同名のフォルダ)

×:ProcData¥AAA¥BBB¥CCC


(10)次のメッセージが表示されます。MS_Readerは、筆者が別に作成した手書き答案の採点プログラムと併用して使用することもできますが、今回の処理ではそのような形では運用しませんので「いいえ」ボタンをクリックしてください。


(11)専用画像の作成が完了すると、次のメッセージが表示されます。OKをクリックしてください。


(12)「終了」ボタンをクリックして、変換作業を終了します(画面下・中央の「画面の初期化」ボタンをクリックすれば、続けて他のクラス/講座の画像を同様に処理することも可能です)。

変換後のファイル名はProcDataフォルダ内に作成した変換先フォルダの名称+01から始まる連番となります。

5.テンプレートとして登録

筆者の作成したマークシートリーダーでは、マークの読み取りに際し、まず特徴点(マークシート画像内のトリプルドット:■■■ )をコンピュータの眼である OpenCV を用いて探し出し、三つの ■ のうち最も左の ■ の左上隅を座標原点(0,0)として、ここからの距離情報を利用してマークシートの第1列を画像として切り出し、二値化・色の反転処理を行って、さらにそこから1行ずつ「行の画像」を切り出し、この「行の画像」を選択肢数個に切り分けて白面積を計算、それが大きい場合に「マークあり」と判定しています。

このため最初にマークシートの特徴点の位置と各列の左上隅及び右下隅の位置を座標として登録し、これをそのマークシート形式の定型フォーマット(=テンプレート)として利用できるように名前を付けて登録する処理を行います。

テンプレートの名前の意味は、次の通りです。

例:R25C04D19

1列あたりの行数・全列数・選択肢の形式と選択肢数を「行・列・選択肢」順に並べています。
R は Row (=行)、すなわち1列 25 行より成ること、
C は Column (=列)、すなわち4列あること、
D は Double 型、すなわち複数マーク対応で、1行あたりの選択肢数は 19 個。
(ここが S の場合は Single 型、複数マーク不可)

Word や Excel で作成したマークシートを、同じインクジェットプリンタで印刷して使用しているので、試験を実施する度にテンプレートを登録する必要はないはずなのですが、筆者はなんとなく不安で、毎回新しくテンプレートを登録し直して作業しています・・・

テンプレートの登録方法は、次の通りです。

(1)「2 テンプレート」をクリックして表示されるサブメニューから「テンプレートの新規登録」をクリックして選択します。


(2)別のWindowが開き、次の画面が表示されます。画面右上の「取得」ボタンをクリックします。


(3)ファイル選択ダイアログが表示されます。任意のマークシート画像を1枚選んでクリックして選択してください。下のファイル名欄にクリックした画像の名称が表示されていることを確認して、「開く」ボタンをクリックします。


(4)選択したマークシートが表示されます。画面右上の「マーカー」オプションボタンをクリックしてください。


(5)画像左上の特徴点部分が3倍の大きさで拡大表示されます。特徴点画像の左上位置をポイント(マウスのカーソル:+の中心を合わせる)してクリックしたらそのまま指を離さずに特徴点画像の右下へドラッグしてください。ドラッグ中は黒い太い枠線(=ラバーバンド)が表示されます。

赤枠の中、ラバーバンドの様子がよくわかるように、特徴点画像より少し大きめにドラッグしています。


実際は、次の図のように、ラバーバンドが特徴点画像の外側をぴったり包む(両者の幅と高さが同じになる)ようにドラッグします。


(6)ドラッグ終了時に矩形選択された部分が特徴点画像としてコピーされ、下の図のように表示されます。照合手法は自動的に設定されますので、変更しないでください。続けてコンピュータの眼である OpenCV がマークシート画像内の特徴点を見つけることができるか、どうかのテストを実行します。

「マーカー画像の読み取りテスト」ボタンをクリックしてください。


(7)OpenCVが発見した特徴点画像の位置が赤い矩形で表示されます。特徴点画像を完全に一致していることを確認し、表示されるメッセージを読んでOKをクリックしてください。


(8)選択対象グループの「解答欄」オプションボタンをクリックすると、案内バルーンが表示されます。マークシートの1列あたりの行数と、マークシート全体の列数、1行あたりの選択肢数をコンボボックスの選択肢から選んで順に設定します。


(9)次の図は、複数選択可能なマークシートの設定例で、行数・列数・選択肢数をそれぞれ入力した直後の状態です。複数マークを許可するか、どうかの設定を行います。

【重要】
複数マークを許可する場合は「複数マークによる採点を実施」チェックボックスをクリックして、チェックが入った状態 にしてください!!

GUIのデザインが悪いためか、作った本人でも! この設定の操作を時々忘れます。複数選択可能なマークシートのテンプレート設定を行う場合は、くれぐれも注意してください。


(10)マークシートの1列目から順に、その座標を取得します。1列ラベルの左のオプションボタンをクリックしてください。マウスカーソルの形状が+になります。

次の図に示したように、まずマークシートのマーク欄枠の左上をクリックし、そのまま指を離さずに、第1列めの右下隅へ向かってドラッグしてください。なお、ドラッグ中は、細い点線のラバーバンド矩形が表示されます。

設問番号欄を含めないようにご注意願います。
必要な座標は、マークシート欄の座標です!


列の右下隅までドラッグした状態を示します。


ドラッグを終了する(マウスの左ボタンから指を離す)と、選択範囲が赤の矩形で囲まれます。取得できた第1列目の座標が画面右のラベルに表示されます。

第1列めの範囲を指定し、座標を取得したところ

【重要】
この作業にマーク読み取りの成否がかかっています!
くれぐれも慎重に、正確に、作業してください。

うまく列を選択できなかった場合は、「再範囲選択」ボタンをクリックして作業をやり直すことができます。


(11)以降、4列目まで同じように作業します。4列目の座標を取得できたら、「保存」ボタンをクリックして取得した座標を ini ファイルに保存します。

保存処理が完了するとメッセージが表示されます


(12)最後に「終了」ボタンをクリックして、テンプレート作成の画面を閉じます。

ボタンは画面右下隅にあります。


これでマークシートを読む準備ができました!

6.マーク読み取りを実行

(1)最初に使用するテンプレートを選択します。

「2 テンプレート」をクリックするとサブメニューが表示されます。
「テンプレートの選択」を選んでください。


(2)テンプレートの選択画面が開きます。使用したいテンプレート名をクリックして反転表示させ、「決定」ボタンをクリックしてください。


【参考】テンプレートの削除方法
必要のなくなったテンプレート名をクリックして選択、「テンプレートの削除」チェックボックスをチェック、「実行」ボタンをクリックすれば不要なテンプレートを削除できます。削除したテンプレートを元に戻すことはできません。テンプレートを削除する際は、その要不要に十分ご注意ください。

(3)次のメッセージが表示されます。これはメニューの「3 作業フォルダ」をクリックすると表示されるサブメニューの「作業フォルダの選択」をクリックした際に表示されるメッセージと同じものです。「はい」ボタンをクリックしてください。


(4)フォルダの選択ダイアログが表示されます。ProcData フォルダ内の読み取りたいマークシート画像のあるフォルダをクリックして選択してください。下のFoleder部分に選択したフォルダ名が表示されたことを確認して、「OK」ボタンをクリックしてください。

選択するのは「ファイル」ではなく、「フォルダ」です。


(5)テンプレート名と関連付けて保存されている特徴点画像が見つかった場合は、それを赤の矩形で囲んで表示します。また、特徴点画像からの距離座標を用いてマークシート欄第1列の1行目がどこにあるのかを計算し、その位置をこちらも赤い矩形で囲って表示します。

【参考】PCによっては、ここで Python Engine の初期化に時間がかかることがあります!

次の図のように表示されれば、マークの読み取り準備は完了です。

諸設定が意図した通りに反映され、OpenCVが正しく動作していることを確認したら、
「OK」ボタンをクリックしてください。


(6)マークの読み取りを実行します。案内バルーンが表示されますので、その下にある「読む」ボタンをクリックしてください。


Python4Delphi が使用できる環境(組み込みPython環境を入れた Python39-32 フォルダが MS_Reader.exe と同じフォルダにある場合)ならば、P4D チェックボックスに自動的にチェックが入り、Python 用のOpenCVを用いてプログラムは動作します。


Python4Delphi が利用できない場合、プログラムはDelphi用のOpenCVを利用して動作します。

画面下に表示されている Grid コントロールにすべてのマークシート画像の読み取り結果が表示されたら、マークの読み取りは完了です。通常の動作モードでは、マークの読み取り完了を知らせるメッセージは表示されません。

複数選択可能なマークシートの場合、空欄や3個以上マークされている等、
読み取り結果に何らかの問題がある場合は「999」と表示されます。

【重要】二値化閾値の修正方法(20240707追加)

マークが「うすい」場合、これを正しく読み取ることができず、「空欄」と判定して「999」と表示される場合があります。同じ理由で、複数マークされた解答欄の「1の位」が読めなかった場合も、読み取り判定は「マークの状態に問題あり」となり、「999」と表示されます。

これらの場合は、この後、実行する「読み取り結果のチェック」時に、該当箇所の解答欄が赤枠で囲まれて表示されますので、マークの状態をヒトの眼で確認し、読み取り結果を修正できます。

最も困るのが、複数マークされた解答欄の「10の位」のマークは薄くて読めなかったが、「1の位」のマークの読み取りには成功している場合です。この場合は正しく読み取れた「1の位」のマークが読み取り結果として表示されてしまいます。大変申し訳ないのですが、MS_Reader.exe のチェックプログラムは、この誤読を見つけることができません!!(これは原理的な問題なので、チェックする方法がありません)

この事故を防ぐには、事前に読み取りテストを十分に行って、読み取りパラメータを調整するしか方法がありません。具体的には、最もマークの濃度が薄い受験者のマークシートが正しく読めるようになるまで、閾値の値を1ずつ大きくして読み取りテストを実行します。筆者の行ったテストでは、デフォルト設定の閾値(180)では正しく読めなかったマークも、閾値を大きくすれば読めるようになりました。

「塗りつぶす」方式でなく、より簡易な「線を引く」方式でマークするシートを用いて行った読み取りテストの例

「64」と読むべき箇所の「10の位」を「空欄」と判定、「1の位」は正しく読めた場合、プログラムは読み取り結果を「4」と表示してしまう。


閾値を「1」大きくすると・・・

正しく読めるようになりました。


ごく薄いマークも正しく読めるようになるまで、この操作をくり返します。筆者の行ったテストでは、閾値を1ずつ大きくすることで、指示通り普通の濃さ(マーク箇所の数字が読めなくなる濃さ)でマークされたシートであれば、最終的にすべてのマークを正しく読めるようになりました(上記のマークシートを使用して行った実験では、最終的にすべてのマークを正しく読めた段階で、二値化の閾値の値は「184」でした。なお、このマークシートは後日公開する予定です)。

ただ、あまりにもマークの濃さが薄い場合は「原理的に読めません」ので、「対応不可」としてヒトの眼で読むしかないと思います・・・。

そのような事態にならないよう、予め受験者に対し「薄いマークは読み取れない」旨の注意を徹底しておく必要があります。マークシートを用いた試験では、これが最も重要なことかもしれません。


【参考】Grid コントロールの高さを変更する方法

Grid コントロールの高さは自由に変更できます。マークシート画像と Grid コントロールの境界部分にマウスカーソルを持って行く(ポイントする)と、=の上と下に上下向きの矢印のついたポインタ形状に変化する場所があります。この部分を上下にドラッグすることで、Grid コントロールの高さを変更することができます。

Grid コントロールの高さを1行分にしたところ

7.マーク読み取り結果のチェック方法

(1)マークの読み取りが完了したら、結果をチェックします。設問数が100である場合はそのまま「Check!」ボタンをクリックしてください。

Check! ボタンをクリックして、読み取り結果を確認します。


設問数が100 未満の場合、空欄その他の判定フラグである「999」が多数入力されていますので、チェック時にそれらのチェックを省略する設定を行います。

例えば、設問数が「80」である場合、4列目の設問「81」以降の「999」はチェックの必要性がありませんから、Skip チェックボックスにチェックして、4列目のコンボボックスに選択肢から「81」を選択します。「覚」ボタンをクリックすると、この設定を記憶します(他のクラス/講座のマークシートを読み取る場合は記憶させてください)。この設定を行ってから、Check! ボタンをクリックして読み取り結果のチェックを実行してください。


(2)読み取り結果に問題があると判定された場合は、次のように「問題あり」と判定された箇所が赤い矩形で囲まれて表示されます。(この場合は、マークが横に長すぎて隣のマークの領域に入ってしまっているのだと思います)

実際の画面では、14 設問目の「999」は青く反転表示されています。
(画面をキャプチャーした際、青の反転表示が消えてしまいました)


確認を行った結果、マークが「15」であり、正解と見なせる場合は Grid コントロールの「999」を消して「15」と入力し、読み取り結果を修正することができます。

読み取り結果を「15」に変更したところ


ちなみにこのような場合、「P4Dを使用」のチェックを外し、判定領域をマーク画像の中心付近のみに設定して読み直せば正しく読めるようになります。(ただし、動作速度は遅くなります)


読み取りパラメータを上のように変更して再度マーク読み取りを実行した場合、

「999」表示は消え、さっきは読めなかったマークを正しく読むことができました。


(3)再度「Check!」ボタンをクリックして、チェックを続行します。

10の位に二つマークがある場合等、不正解と見なせる場合は、「999」を修正せず、チェックを続行します。
続けて「Check!」をクリックしてください。


次のメッセージが表示されたらチェックは完了です。

8.CSV形式で出力

マークの読み取り結果の確認作業が完了したら、Grid コントロールに表示されているデータをCSV形式でファイルに出力できます。このCSVファイルは筆者作の採点結果通知作成プログラムから読み込んで採点結果通知票の作成に利用できます。Excel Book にもこのデータを書き出すことができますが、複数マーク対応の採点結果通知を作成できる Excel のワークシートは作成しておりませんので、ここではその処理方法の詳細は説明しません。

CSV形式で出力する方法は、次の通りです。

画面右下の「ファイルへ出力」グループの CSV オプションボタンをクリックして選択し、「書き出し」ボタンをクリックします。


書込みが完了すると、次のメッセージが表示されます。


表計算ソフトその他を用い、ご自身で採点結果を処理される場合は、出力先をメモしてください。

出力されたCSVの内容は、次の通りです。

1行目は「設問番号」、A列が「マークシート番号(=出席番号)」です。

9.採点結果通知シートの作成方法

採点結果通知の作成方法は、当Blogの過去記事をご参照下さい。

10.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

100選択肢に対応したマークシートリーダー


先日、電車にゆられていたら先輩が。

「選択肢がたくさんあると、マークシート使うの、難しいかなー?」って。

なんかおもしろいこと、ないかなー☆って、毎日、ひまなんだもん。

すぐに出来そうな気がしたので、さっそく大語群に対応したマークシートリーダー作成にチャレンジ。

今までのは数学や教科「情報」の試験用に作成した16選択肢が最大だったが。

数学の試験用に作成したマークシート(マーク部分は-記号)
マークの色が濃いのは、開発初期のマークシートの画像であるため。
教科「情報」の試験用に作成したマークシート(選択肢の番号はゼロ始まり)
経験を積む中で、誤判定を防止するため、マークの色はどんどん薄くなった。

今回、作成したマークシート(最終的なかたち・Excel で作成)。

大語群に対応したマークシート(選択肢の番号は0ー99、合計100)、遂に完成!

正直、思ったほど、かんたんではありませんでした!!

【もくじ】

1.最初に作ったのはB4縦型のマークシート
2.次に作ったのはA4横型のマークシート
3.Excel でマークシート作成に挑戦
4.マークシートを最適化
5.読み取りプログラムも修正
6.発見した問題点と解決策
7.まとめにならないまとめ
8.プログラムのダウンロード
9.お願いとお断り

1.最初に作ったのはB4縦型のマークシート

選択肢の数が多いことを、ここでは『大語群』と呼ぶことにする。この大語群に対応したマークシートを作るにあたり、最初に決めておくべきことはもちろん選択肢の最大数。30個もあれば十分な気もしたが、「大きいことはいいことだ!」とも言うし、どうせ作るなら100個まで対応できるようにしようと決心。

数年前にマークシートリーダーを作ったとき、選択肢数50個に対応した複数マーク読み取り可能なプログラムを書いた記憶があり、10の位と1の位を分けてマークする次のような形式のマークシートがすぐに思い浮かぶ。1行あたり、2個までのマークを読み取れるようにコードを修正すれば、このマークシートで選択肢の番号を0-99として、計100個の大語群を使った試験にも対応できるはずだ。

10の位のマーク欄が空欄なら、プログラムは1の位のマークのみを読むよう設定


このイメージを実現するにあたり、差し当たって問題になるのはマークシート用紙の基本サイズ。さすがにA3サイズの用紙は、マークシートとして使うには巨大すぎる気がする・・・が、1行あたり10の位のマークに①~⑨で9個、1の位のマークに⓪~⑨で10個、合計19個のマークを用意して、得点設定は1設問1点で合計100点とするためには、当然100設問分の行を用意しなければならない。

1列50行で2列作成するとなると・・・、やっぱり、B4版で、縦置きか?

これまでのマークシートは Word で作成していたので、今回も Word を利用。・・・と言うか、本当は印刷設定の自由度が大きい Excel を使いたいのだが、Excel で縦楕円の丸囲み数字を上手に作成する方法がわからない。そこで縦楕円の丸囲み数字が簡単に作成できる Word を利用した・・・というのが正直なところ。

ちなみに Word で縦楕円の丸囲み数字(=「囲い文字」というらしい)を作成する方法は・・・

Word なら、Font は「メイリオ」を選択(フォントサイズを大きくしない場合)、丸囲みしたい数字を半角で入力、入力した数字をマウスでドラッグして選択してから、フォントリボンの「囲い文字」アイコンをクリックすると・・・

赤い枠で囲んだのが「囲い文字」を作成するアイコン。
数字を入力して、ドラッグして選択したのち、これをクリック。


ダイアログが表示されるので、スタイルを設定して・・・

スタイルは「文字のサイズを合わせる」を選択。


さらに数字の選択状態は解除しないまま、段落リボンの「拡張書式」をクリックして、表示されるサブメニューのいちばん下にある「文字の拡大/縮小」をクリックして、さらに表示されるサブメニューの「66%」をクリックすれば・・・

マークシートのマーク領域(縦楕円の囲い文字)を作成


思った通りの囲い文字が完成!


あとはマークシート用途に利用できるよう、色の設定を薄めに変更する等して、必要な選択肢の数だけこれを作成すればいいんだけど・・・

これを Excel で実現する方法がわからない・・・


そのような理由から、とりあえず Word で作成してみたB4版・縦置き型のマークシート。
思ったより巨大で、マークするのがたいへんな気が。

マークするだけで疲れた・・・


読み取り実験用に設問番号1から順に、読み取りデータが設問番号と同じになるようマークしてみる。
100個目は1の位の「0:ゼロ」をマーク。これで1から99と0(ゼロ)で、合計100の選択肢が使える大語群対応型マークシートが完成・・・したと思ったんだけど。

複数マークの読み取りを可能にするため、リーダーのプログラムを少し変更。

Delphiを起動して、マークシートリーダーのプロジェクトファイル一式をコピーして、新たな複数マークの読み取りに対応したプロジェクトを作成。

マーク読み取り手続き部分のコードを次のように変更。最初に手直ししたのは、P4Dを使ったスクリプト部分。

      //複数マークの読み取り方法
      if (Copy(strMS_Type,10,2)='19') and (chk_MultipleMarks.Checked) then
      begin
        //選択肢数が19で、複数マーク許可であった場合
        StrList.Add('                var1.Value = str(res)');
      end else begin
        //複数マークは不許可であった場合
        StrList.Add('                var1.Value = "99"');
      end;

Python側で読み取った値をDelphi側で処理する部分も変更(一部を抜粋)。

//選択肢の始まりは「ゼロ」
  if (Copy(strMS_Type,10,2)='19') and (chk_MultipleMarks.Checked) then
  begin
    //複数マークに対応
    //strAnsList[intSG_k]の文字数を調査
    strCount:=ElementToCharLen(strAnsList[intSG_k],Length(strAnsList[intSG_k]));

    //チェック内容は、以下の通り
    {
    文字数が2文字の場合、末尾の1文字を取得する
    10 -> 0
    11 -> 1
    19 -> 9
    末尾1文字がマークした選択肢の番号になる

    文字数が5文字の場合、
     1 10 -> 2文字目が1、末尾2文字が10 -> 10
     2 11 -> 2文字目が2、末尾2文字が11 -> 21
     3 12 -> 2文字目が3、末尾2文字が12 -> 32
    (2文字目×10)+(末尾2文字 - 10)がマークした選択肢の番号になる
    }

    case strCount of
      2:begin
        //2文字の場合は、末尾1文字が選択した選択肢の番号
        StringGrid1.Cells[intSG_Col,intSG_Row]:=RightStr(strAnsList[intSG_k],1);
      end;
      3:begin
        //空欄と判定された場合
        if strAnsList[intSG_k]='999' then
        begin
          StringGrid1.Cells[intSG_Col,intSG_Row]:=strAnsList[intSG_k];
        end;
      end;
      5:begin
        //(2文字目×10)+(末尾2文字 - 10)がマークした選択肢の番号
        StringGrid1.Cells[intSG_Col,intSG_Row]:=IntToStr(
          (StrToInt(Copy(strAnsList[intSG_k],2,1)) * 10) +
          (StrToInt(RightStr(strAnsList[intSG_k],2))) - 10);
      end;
    end;
  end else begin

次に、P4Dを使用しないDelphi用のOpenCVを利用したマーク読み取り部分のコードも変更(一部を抜粋)。

  //1行につき選択肢数分Loopする_複数選択肢に対応(New)_20240614
  if (Copy(strMS_Type,10,2)='19') and (chk_MultipleMarks.Checked) then
  begin
    //複数選択可能な場合_選択肢の数だけLoopする
    for p := 0 to intCol-1 do
    begin
      //対象値pが平均値の3倍より大きいか、どうかでマークありと判定
      if AryVal[p]>dblAvg * intKeisu then
      begin
        //マークありとした判定の数を記録
        q:=q+1;
        //マークした番号(記号)を記録
        //intMark:=p+1;
        //10の位(0-8)
        case p of
          0:strMark_A:='1';
          1:strMark_A:='2';
          2:strMark_A:='3';
          3:strMark_A:='4';
          4:strMark_A:='5';
          5:strMark_A:='6';
          6:strMark_A:='7';
          7:strMark_A:='8';
          8:strMark_A:='9';
        end;
        //1の位
        case p of
           9:strMark_B:='0';
          10:strMark_B:='1';
          11:strMark_B:='2';
          12:strMark_B:='3';
          13:strMark_B:='4';
          14:strMark_B:='5';
          15:strMark_B:='6';
          16:strMark_B:='7';
          17:strMark_B:='8';
          18:strMark_B:='9';
        end;
      end;
    end;
    //Loop終了時にマーク数を判定
    if q=0 then
    begin
      //マークした番号がない場合
      iArr[i,Rep]:=999;
    end else begin
      //マークした番号があり、それが一の位である場合
      if (q=1) and (strMark_A='') then
      begin
        //マーク数が1、かつ十の位が空欄であったら
        iArr[i,Rep]:=StrToInt(strMark_B);
      end else begin
        //マーク数は1だが、それが十の位であったら
        iArr[i,Rep]:=100;
      end;
      if (q=2) and (strMark_A<>'') and (strMark_B<>'') then
      begin
        //マーク数が2、かつ十の位と一の位がともに空欄でなかったら
        strMark:=strMark_A+strMark_B;
        iArr[i,Rep]:=StrToInt(strMark);
      end;
      if q>2 then
      begin
        //トリプル以上のマーク数を見分けるフラグは100
        iArr[i,Rep]:=100;
      end;
    end;
  end else begin


Delphiでマークシートリーダーを作成する方法の基本は過去記事をご参照ください。

マークの読み取りそのものは「絶対成功する」自信があった(?)ので、複数マークの読み取り処理を既存のプログラムに追加すれば、速度的なことも含めて楽勝でプログラムは完成するはず・・・だったんだけれど。

実際に上のB4版・縦置き型マークシートをスキャンして読み取りテストを行ってみると・・・

P4D利用時の読み取り結果は期待した通り、100 %正確にマークの読み取りに成功するが、P4Dを利用しない場合に不具合が発生。50設問目は正しくは「2」と読み取らなければならないはずなのに、読み取り結果の表示には、なぜかトリプルマークの判定結果である「100」が表示されている。

※ この時点では、必要数以上にマークがあった場合の表示フラグとして「100」を使用していた。
※ 最終的に、読み取れない解答欄は全て空欄の表示フラグ「999」で示すようプログラムを修正した。

「100」は3つ以上のマークがあった場合に表示されるはずなんだけど?


さらに、よく見てみると 100 設問目もヘン。91、92、・・・、97、98、99 と順調に読み取って、最後は「 0:ゼロ」とくるはず!なのに、読み取り結果はトリプルマーク以上の判定結果である「100」がここにも登場。ヒトならともかく、機械が勢い余るはずもなく、誤認識の原因はまったくもって不明。

どうみてもマークしたのは「0:ゼロ」なんだけど。


今までさんざんテストして、読み取りパラメータ設定も変更の必要が「ない」ところまで煮詰めたと思っていたのに、この結果には唖然とするしかなく、悪夢を見ているのではないかと思ったが。

現実は現実。

変更したコードを見直してみるが、おかしなところは見当たらない(ように思う)。
実際、大多数のマークは「ちゃんと読み取ってる」し・・・

なんで、部分的に読めない箇所があるのか???

読めないなら読めないで、「全部」間違うのが機械だと思うんだけど。

仕方がないから、パラメータ設定をいじってみるが・・・

これがデフォルトのパラメータ設定。
(自分的には、変更の必要がないと思えるところまで、さんざん修正を繰り返して決めた値)


パラメータをどう設定しても、一部のデータを誤って読んでしまう・・・。

例えば、閾値を「200」、判定領域を「20」に変更した場合、

47、48、49ときて、次は2のはずなのになぜか「42」
機械のクセに、勢い余ってるとしか思えない・・・。

こんなプログラムは使えない!!

2.次に作ったのはA4横型のマークシート

誰も助けてくれる人なんていないから、問題は自分で解決するしかない。まぁ、問題そのものを自分で作り出しているとも言えるわけで、自業自得と言えばそれまでのこと。自分以外の誰も困ってないし、それを幸いにあきらめてしまうのがいちばん簡単なことだが、それは最終手段。

原因はわからないが、今まで起きたことのないことが起きている、つまり、今までと違うことをしてるから、そこに問題の発生する原因そのものがあるはずだ。何が違うのか、そこを考えてみる。

今までと違うのは、まず、マークシートのサイズそのもの。B4版なんて使ったことがない。もしかしてそれが原因か? 判定プログラムでは行を図として切り出して、さらにマーク1つずつに分解し、二値化して「白」面積が大きいものを「マークあり」と判定しているから、二値化の閾値の設定にもよるが面積的な部分にも誤認識の原因があるような気もしてきた。そうでなくても、実際に使ってみて、やはりB4サイズは「マークシートとして大きすぎる」気がしたのは、ほんとう・・・。

もし、マークの読み取りプログラムそのものに誤りがあるなら、全てのマークを正しく読めないはずだが、ほとんど正しく読めているから、読み取りプログラムそのものに致命的な問題はない・・・はず。

そこで、これまでに正しく読み取れたものとサイズ的に同じ「A4版・横置き型」のマークシートを作成して実験してみることにする。

そう思って作成したのがこちらのマークシート。縦置きにしなかったのは、「今までと同じにする」という部分にあくまでもこだわった結果。

かなり無理して「詰め込んだ」感、満載。


さすがにA4版・横置き型で1列50行のマークシートは(自分の技術では)Word で作成できず、作成にあたっては(念願の?)Excel を使用。Excel で作成した際の画面はこんな感じ。

縦に長い楕円の囲い文字の作り方がわからず、仕方がないから丸囲みの番号でマークを作成
どこか、なにかが「チープな感じ」で、出来栄えもいまいち。


これで実験すると・・・、P4Dを使った場合からして

まったく読めてない!


高速読み取り処理が可能なP4D環境で正しく動作しなかった時点で(これはダメだ)と思ったが、とりあえず非P4Dモードで動かしてみると・・・

B4版使用時より、さらに悪い結果に。


B4版使用時は「唖然」とする思いであったが、今度は「暗澹たる」思いが。

この結果を目の当たりにしたときは、驚愕のあまり、言葉を失い、ついでにやる気もほぼ全部失い、PCの蓋を閉じて(この表現でいいのか?)、火酒を求めてバイクで現実から逃走・・・

あの土曜日の夜は、まじで、つらかった。

ひー(こころの声)

今、冷静になって考えると、P4Dモードでほとんど読み取れてないのはおそらくマークシートの罫線に問題があり(太すぎ)、これが複数マークの判定につながったのではないかと思えてならないが、最初からマークシートの作り自体が気に入らなかったこともあり、自分史的には・・・この実験自体を「なかった」ことにして、心のバランスを保つことに決定。

ただ、まだ「あきらめる」という気持ちには到底なれないので、このピンチをまたとないチャンスと前向きに捉え、Excel で縦長楕円の丸囲み文字を作成するところからチャレンジを再開。

あきらめられない以上、自分も、プログラムも良くなるしか「ない」。
それが嫌なら、はじめからこんなこと、しないほうがイイ。

このチャレンジは、僕にある唯一の「自由」なんだ。
暗澹たる思いなんかで、終わりにはしたくない。

3.Excel でマークシート作成に挑戦

Excel を起動し、何も入力されていない白い画面をじっと見つめて考える。

(縦長の楕円で、囲い文字をつくるには・・・)

経験から唯一思いつく方法は、図形(楕円)をセル内に収まるように挿入して右クリック、テキストの編集を選択して、中に数字を入力する方法だ。楕円の挿入方法は次の通り。

挿入タブをクリック ⇨ 図のリボンにある図形から楕円を挿入


まずは、準備作業。

(楕円を挿入するより先に)あとあと作業しやすいよう、画面右下の「ズーム」で画面表示を拡大(238%くらいにした)して、全セルを選択(下図を参照)。で、列幅を28ピクセル、行の高さを32ピクセルくらいに設定。

全セルを選択し、列幅と行の高さを変更する


B2のセルに収まるよう、楕円を挿入(ズーム300%)。

楕円を挿入


挿入した楕円を右クリックして、表示されたサブメニューから「テキストの編集」を選択(左クリック)。

図形の中にテキストを挿入


半角で1と入れてみた。

数字は入ったが、位置がよくない・・・


ホームタブをクリックして、配置リボンにある「上下中央揃え」と、その下の「中央揃え」をクリック。

数字の位置はいい感じになった。


あとはマークシートのマークらしくするため、楕円をクリックして選択すると表示される図形の書式タブをクリックし、図形のスタイルリボンのコマンドを使い、楕円の中を白くして、囲いを灰色に設定。

マークシートのマークらしくする


フォントの色も灰色に変更。

数字の色も灰色にする


で、セル内での図形オブジェクトの位置を微調整。

セル内で中央に揃うよう、楕円を選択して左右の矢印キーで位置を微調整


できた!

スキャナーで実際にスキャンしてみた結果から言うと、
実際に使用するマークシートではもう1段階濃い灰色を選んだほうがよさそう


あとは、コレを等間隔で上下の位置もそろえて並べれば・・・いい・・・んだが、その方法がわからない。

藁にも縋る思いで、Google先生に訊ねると・・・

単に「楕円を挿入したセルをクリックして選択し、オートフィルの機能を使って右方向へコピー」するだけ! だよって。

半信半疑で、やってみた。

楕円ではなく、セルを選択


表示された緑の枠の右下隅にあるハンドルをクリックして選択して、そのまま右へドラッグ。
すると・・・

祈るような気持ちとは、まさにこのことか・・・


マウスのボタンを離すと、表示されたのは・・・

思った通りにコピーできた!


これだ。これ!
これを待っていたんだ。

Google先生、ありがとう!

あとは数字を変更すれば・・・

マークシートのマークができた!


こうして得た知識をベースに、これまでの経験を加えて Excel で作成したマークシートがこちら(枠の線の設定状態がよくわかるように、枠線の表示はONに設定した状態)

マークを塗りつぶす際に、上下左右のマークに影響が及ばないだけの間隔を確保


ページレイアウトタブの配置リボンの「配置」をクリックして、「枠線の表示」をオフに設定。

「枠線の表示」をクリックする度に、表示のONとOFFが切り替わる


先の実験では、罫線の太さで痛い思いをした(?)ので、再びその轍を踏まないよう、罫線はいちばん細いものを選び、色もオレンジに設定。こうしておけば二値化する際に、罫線は完全に消えるはずだ。

注意:この時点では、そう、考えて罫線の色を設定しましたが、以下で述べる通り、いちばん細い罫線に対する色の設定は、印刷時に無効になり、印刷色は必ず黒になります!

確か、いちばん細い罫線はこれだったはず・・・


で、罫線の色も文字の色(=マークの色)と同じ薄い灰色に設定して試しに印刷してみると、なにか違和感を感じる印刷物がプリンターから排出された。よく見ると罫線の色が濃い! 指定した灰色でなく、普通の黒のような気がしてならない。他の灰色を選んでも、印刷すると罫線の色は「まったく変わっていない」ように見える。もしかして、色の濃さの設定が反映されていない?

(オレンジ色にしてみるか?)

早速、設定 ⇨ 印刷を実行して確認 ⇨ 結果は「黒いまま!」

再び、Google先生にお伺いをたてて知った驚愕の事実。

「Excel はその仕様のため、いちばん細い罫線は印刷時に必ず黒で印刷されてしまう」とのこと。

まじですか? まったく知りませんでした!!

あわてて2番目に細い罫線に変更。色はオレンジ色を指定(この色がなぜか、すーぱー気に入った)。

そうこうして、ようやく、これなら大丈夫と思えるマークシートが完成。

上記の方法で枠線の表示はOFFに設定した状態の画面。
自分的には、満足できる出来栄え。

4.マークシートを最適化

完成したマークシートの全体のイメージはこんな感じ。

1列あたり25行×4列、1行について19選択肢(10の位:1-9、1の位:0-9)、A4版・横置き、
最大100設問に対応


ちょっとマークが小さいような気もしたが、数学・情報用に作成した1行あたり16選択肢のマークシート同等に、隣り合うマークどうしの間隔もあけることが出来た気がする。これが近すぎると乱暴にマークされた場合、「複数マークあり」と判定してしまう危険性が高まってしまう。

また、1列あたり25行の設定としたことで、上下のマークの間隔も十分広くなった。B4版・縦置きの1列50行やA4版・横置きの1列50行よりも遥かに圧迫感は減少している気がする。

でも、試しに100設問分ぬってみたら、やっぱり、疲れた・・・。100設問分マークするってことは、その約2倍マークしなければならないから、疲れて当然と言えば、当然。

これをスキャンして、最終動作確認。


上のマークシートを、実際にスキャナーでスキャンしてJpeg画像に変換し、マークの読み取り処理を行ってみた。結果はPython環境を使っても、使わなくても、読み取り成功率は100%、ようやく期待通りに動くようになってきた。でも、途中、マークシート作成作業での失敗がなければ、Excel を使って(縦長楕円の囲い文字で)マークシートを作る技術は習得できなかった。「失敗は成功のもと」というけれど、今回あらためて諺の重みを実感。

次はマークシートの印刷の濃度の調整(最終仕上げ)。・・・と言うのも、実はマークの読み取り結果をExcel で処理して採点結果の通知シートを作ってる時は全く問題にならなかったことが、読み取ったマークシート画像に直接 〇 や × 、個々の設問の得点や配点、合計点等を入力して返却するように処理系全体を改良したら、これまで思っても見なかったことが重大な問題となってきたのだ。

次の画像を見れば、それは一目瞭然。

マークシートがほとんど見えない!


マークシートの印刷濃度を薄くしすぎると、スキャナーで読み取る際に枠やマークが本当に薄くなってほとんど見えなくなってしまうのだ。単にマークの有無を読み取るだけなら、■■■ からの距離でマークを切り出して二値化し、白面積を計算しているだけだからマーク以外の画像は真っ白でも何の問題もない(むしろ、それくらいの画像の方がより確実にマークを読み取れる)のだが、スキャンした画像そのものを採点結果通知に再利用するとなると、枠やマークがある程度は「見える・読める」ようにスキャンしなければならない。

マークシートのマークや罫線枠の灰色の濃度を少し濃く(下図を参照)して画像をスキャン、どの程度見えるようになったか、確認してみる。

1段階濃い灰色を指定(実際には Ctrl + A でオブジェクトをすべて選択してから設定)


スキャンして画像を表示してみると・・・

マークは読めるようになったが、罫線枠はまだ見えにくい。


罫線の色をオレンジ色に設定したら、それがとても気に入ってしまったのだが、残念ながらスキャンすると罫線枠はほとんど消えて見えなくなってしまう(マークの有無のみを正確に読み取るという意味では、それは実に理想的なのだが)。ただ、マークシート情報の取得プログラムでは、マークひとつひとつを切り出すために罫線の枠の座標を利用しているから、罫線枠の左上隅と右下隅は座標を取得する場面では確実に見えるようにしておきたい。そこで、罫線枠の左上隅と右下隅だけは線の色を灰色にすることにした。(実は、上の画像はそれがほどこしてある画像)

まず、左上隅を設定。

罫線枠の左上隅の「 部分のみ灰色に変更


同様に、右下隅も設定。

罫線枠の右下隅の 」部分のみ灰色に変更


マークシートの情報を取得する際に、罫線枠が十分よく見えることを確認。

すみっこはよく見える!

5.読み取りプログラムも修正

最終的に実用上問題のないプログラムにするため、思いつく様々なパターンで(誤りを含む)マークを作成し、これをプログラムがどのように判定するか、テストしてみた。

テスト用に、次のマークシートを作成。

動作検証用に作成したマークシート
(スキャンしたら、画像中央やや上に横線が入っていた。原因は不明。)


マークシートのスキャンに使っているスキャナーでスキャンすると、時々、黒い線の入ったJpeg画像が生成される。しかも、この黒い線はマークの読み取り判定になぜか?影響を与えない。

上半分だけ塗りつぶしたマークでも、正しく「4」と読んでいる。
複数マークありと判定されないのはなぜ?


この不思議な現象の原因はまったくわからないが、判定に影響を与えないから、これまでは(まぁいいか)としてきたが・・・。

いずれにしろ、このマークシートを使って動作検証を行った結果、先に記した判定プログラムでは対応できない問題が複数あることが判明。検証をくり返し実行して、一つ一つの問題に対応。最終的に完成したのが次のコード。

  //選択肢の始まりは「ゼロ」(1の位を基準)
  if (Copy(strMS_Type,10,2)='19') and (chk_MultipleMarks.Checked) then
  begin
    //strAnsList[intSG_k]の文字数を調査
    strCount:=ElementToCharLen(strAnsList[intSG_k],Length(strAnsList[intSG_k]));

    //チェック内容は、以下の通り
    {
    文字数が2文字の場合、末尾の1文字を取得する
    10 -> 0
    11 -> 1
    19 -> 9
    末尾1文字がマークした選択肢の番号になる

    文字数が5文字の場合、
     1 10 -> 2文字目が1、末尾2文字が10 -> 10
     2 11 -> 2文字目が2、末尾2文字が11 -> 21
     3 12 -> 2文字目が3、末尾2文字が12 -> 32
    (2文字目×10)+(末尾2文字 - 10)がマークした選択肢の番号になる
    }

    case strCount of
      1:begin
        if StrToInt(strAnsList[intSG_k])<10 then
        begin
          StringGrid1.Cells[intSG_Col,intSG_Row]:='100';
        end;
      end;
      2:begin
        //2文字の場合は、末尾1文字が選択した選択肢の番号
        StringGrid1.Cells[intSG_Col,intSG_Row]:=RightStr(strAnsList[intSG_k],1);
      end;
      3:begin
        //空欄と判定された場合
        if strAnsList[intSG_k]='999' then
        begin
          StringGrid1.Cells[intSG_Col,intSG_Row]:=strAnsList[intSG_k];
        end;
        //3文字と判定された場合、十の位の1~9のダブルマークの場合、
        //2文字目は必ず半角の空欄になる
        if Copy(strAnsList[intSG_k],2,1)=' ' then
        begin
          StringGrid1.Cells[intSG_Col,intSG_Row]:='999';
        end;
      end;
      5:begin
        //文字列の置き換え(先頭2文字を抽出&半角スペースを削除する)
        strData:=StringReplace(Copy(strAnsList[intSG_k],1,2),
          ' ', '', [rfReplaceAll, rfIgnoreCase]);
        //Case 5で先頭2文字が10である場合はダブル以上のマークあり
        if StrToInt(strData) > 9 then
        begin
          StringGrid1.Cells[intSG_Col,intSG_Row]:='999';
        end else begin
          //2文字目が半角スペースでなければ処理可能
          if Copy(strAnsList[intSG_k],2,1)=' ' then
          begin
            StringGrid1.Cells[intSG_Col,intSG_Row]:='999';
          end else begin
            //(2文字目×10)+(末尾2文字 - 10)がマークした選択肢の番号
            StringGrid1.Cells[intSG_Col,intSG_Row]:=IntToStr(
              (StrToInt(Copy(strAnsList[intSG_k],2,1)) * 10) +
              (StrToInt(RightStr(strAnsList[intSG_k],2))) - 10);
          end;
        end;
      end;
      6..99:begin
        StringGrid1.Cells[intSG_Col,intSG_Row]:='999';
      end;
    end;
  end else begin

    //複数選択を許可しないマークシートの処理

  end;

end;


ここでいちばん困ったのは、必要以上にマークされていた場合の処理。

複数マークを容認しないプログラムなら、1行について2個以上マークされていた場合は「複数マークあり」を意味するフラグとして「99」、マークなしの場合(=空欄)は「999」というフラグを用意して対応したが、今回のように複数マークを許可し、読み取り結果を 0 – 99 の100分類で表示する場合、空欄すなわち「マークなし」を「999」と表示するのは同じでよいとしても、十の位や一の位のマーク欄それぞれに2つ、ないし、3つ以上マークされていた場合のフラグをどうしたらいいのか? 最適と思われる答えが見つからずにかなり悩んだ。

出来れば、既存かつ(プログラムによっては)数年をかけて動作検証済みの、読み取り結果のチェックプログラムや、採点結果通知のプログラムを修正せずに、それらをこの複数マーク対応採点システムにもそのまま適用できるように、処理の流れを作りたい。

必要数以上のマークがあった場合、当初、選択肢としては決して使うことのない「000」、「100」、「XXX」等をフラグとして利用することも、かなり真剣に考えたが、これらのフラグを新規に採用した場合、これまでに書いてきたマークシートの読み取り結果を記録したCSVファイルを利用して動作するプログラムをことごとく修正しなければならない。そして、それは新しいバグを生むことに、間違いなく直結する。それだけは、どうしても避けたい。

この際、読み取りエラーをすべて「999」で処理すれば、これまでの経験から、読み取り結果のチェックプログラムは確実に「空欄」=「999」位置を教えてくれるし、もし、それが本当に「空欄」である場合は、人が見ればそれは一目瞭然、もし、それが空欄でない場合は、それを見た「人」に、マークの有無 or 空欄 or その他複数マークの判断を委ねればいい。そしてもし、「人」が見て、マークが正しければプログラムの判定結果を正しく修正、そうでなく、マークが「空欄でない」・「必要数以上にマークされていた」場合は、そのまま「空欄として処理(999)」してもらえば、採点結果には一切影響を与えないはずだ。

そう考えて、「トリプル以上のマークあり」をユーザーに伝えるフラグは用意せず、10の位に1つ、1の位に1つ以外のマークがあった場合はすべて同一に「空欄」フラグの「999」で処理することにした。

6.発見した問題点と解決策

上記動作検証用に作成したマークシートで、実際に動作確認を行った結果、ひとつだけ気になった点があった。それは、マークから横にはみ出て(横に広く)マークされると「トリプル以上のマークあり」という判定が出やすいこと。

「12」を読み取れていない。
おそらく1の位の「2」の横棒マークが「1」の領域に侵入している?


マークとマークの間隔を、これ以上広くするのはさすがに困難。1行19選択肢+行番号というマークシートの形式そのものに起因する問題だから、これは試験の問題用紙の表紙に図付きで「横棒型の塗りつぶし禁止」&「なるべく横に広がらないようマークする」注意を載せて、読み取り不能の「999」判定がなるべく出ないようにすることくらいしか、対策を思いつかなかった。

(縦に長い四角形、もしくは縦型の [ ] で数字を囲うことも考えたが、実際には試していない)

Python環境を利用しない場合は、判定領域をマークの中心付近のみに狭めることで読み取り精度を上げることができる。ただし、読み取り速度はかなり遅くなってしまう。

Python環境を使わず、判定領域を70→50に狭くして、実行すれば上の読み取りエラーは解消できる。


マークシートリーダー作成の初期、まだPython環境を利用できなかった頃、少しでも読み取り速度を早くできないかといろいろ考え、二値化後の白面積の計算領域をマークの中心付近のみとすれば、読み取り速度を向上させることができるのではないかと思って作った機能が思わぬところで役に立った!

以上が、解決策とは言えない対策と、読み取り速度を気にしなければ使える解決策。

7.まとめにならないまとめ

(1)実用的ではないかもしれないが、大語群(100選択肢)に対応したマークシートリーダー完成
(2)Excel を使って1行19選択肢で25行4列、A4横置きのマークシートを作成して試験を実施
(3)採点結果通知は付属の ReportCard.exe で作成

ReportCard.exe の使い方は、下のリンク先をご参照ください。

プログラム本体は、この下のダウンロードリンクから取得可能なZipファイルに同梱しています)
同梱した採点結果通知作成用のプログラム


ただし、選択可能な採点オプションの指定は「採点のみ」or「採点と配点」のみとなります(下図の赤枠)。観点別評価の区分を含めて表示するオプションを選択しても、プログラムは複数マークに対応していないバージョンの流用なので、正解マークの位置を正しく表示できません。少なくても観点別評価の区分は表示できるよう、今後プログラムを改良する予定です。

追記 改良したプログラムに更新しました(20240625)

複数選択可能なマークシートについても、観点別評価の区分や正解マークの位置を表示できるよう、プログラムを更新しました。

採点及び観点別評価の区分と、不正解の設問について正解マークの位置を表示
得点は返却用シートの右下に表示

この大語群専用マークシートを使用した試験の実施方法と、試験後の処理方法について次回の記事で詳細を説明する予定です。よろしければ、そちらの記事もご参照ください。

8.プログラムのダウンロード

大語群に対応したマークシートリーダーは、下のリンク先からダウンロードできます。
なお、バックグラウンドでPython環境を利用し、より高速にマークの読み取り処理を実行するには、別途Python環境の組み込みが必要です。動作に必要なライブラリをインストール済みのPython環境は、当Blogの過去記事へのリンクからダウンロードできます。

Python環境の組み込みはカンタンです。ダウンロードしたZipファイルをダウンロードした後、任意のフォルダに展開、生成されたPython39-32フォルダを、そのまま MS_Reader.exe があるフォルダにコピーするだけです。

こちらの大語群に対応したマークシートリーダーは、当ブログの過去記事に掲載した複数選択不可のマークシートリーダーを、複数選択を前提として設計された専用マークシートのマーク読み取りに特化させたバージョン、いわば派生版です。複数選択不可のマークシートの読み取りにも使用できると思いますがテストは行っておりませんので、ダウンロードしたZipファイルを展開して出来る MS_Reader.exe は複数選択可能なマークシートの読み取り処理専用にお使いください。

この記事で紹介した通り、様々な要因から、マークシートによっては(基本設計が同じであっても)マークを正しく読み取れないことがあります。
また、添付した動作検証済みのマークシートをご利用いただいた場合でも、その印刷方法(輪転機使用等でマークが濃く印刷されていた場合)によっては、マークを正しく読み取れないことがあります。印刷用紙は再生コピー用紙で十分ですが、印刷には 必ずインクジェットプリンタを使用 し、スキャンしたJpeg画像において、マークや罫線枠がうっすらと判別できる程度の濃さで印刷していただく必要があります。

以下、読み取りテスト実行時の環境です。

・A4用紙は、(白くない)再生コピー用紙
・スキャナーは有名メーカー製複合機のスキャナー(カラー/読み取り解像度200 dpi)
・PCはPanasonic製Let’s Note CF-QV
・スキャンした画像をこのプログラム用に変換する際の倍率は80%を指定

「1 画像変換」をクリックすると表示されるサブメニューの「専用画像を作成」をクリック
倍率は80%を指定


上記の環境で、筆者がテストした結果を記事としてここに掲載しました。発見した不具合も正直に書きましたが、筆者が発見していない不具合が他にまだあるかもしれません。ですので、ダウンロードしたマークシートリーダーのご使用はあくまでも自己責任でお願いします。

また、派生版であるため、プログラムには Excel Book に読み取り結果を出力する機能がありますが、大語群に対応した採点結果通知作成用の Excel ファイルは、Zipファイルを展開後、 eFile フォルダ内にあるテンプレートから生成できる Excel ファイルをマクロ有効な Excel Book として保存し、これを元にご自身で作成していただく必要があります。※ Zip ファイルに添付した Excel Book は、大語群マークシートに対応しておりません。

採点結果通知が必要な場合、Zipファイルに同梱した ReportCard.exe をお試しください。こちらは「まとめ」で紹介した通り、動作検証済みです。同梱の ReportCard.exe は選択肢が「ゼロ」から始まる教科「情報」用のマークシートにも対応したものです。

※ お使いのPC環境により、Python Engine の初期化に異様に時間がかかったり、おまけの機能である成績一覧表作成時に、罫線位置が誤って描画される不具合があります。罫線の描画に問題がある場合は、罫線機能をOFFにしてデータのみを出力してください。こちらの成績一覧表はメモ程度にお使いください。

なお、大語群対応のマークシートリーダーでは、マークの読み取り結果を最後に一括して表示する速度優先モードは使用できません。

本記事で紹介したマークシートを同梱しました。Zipファイル展開後に作成されるSample_MarkSheet フォルダ内にある R25C04D19.xlsx をご参照ください。

次のリンク先からマークの高速読み取りを可能にする Python 環境をダウンロードできます。なお、プログラムの動作に必要なライブラリはすべてインストール済みです。



この記事で紹介した100選択肢対応マークシートリーダーの使い方は、次の記事をご参照ください。

9.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

無料で使える手書き答案採点補助プログラム

Answer Column Reader

横書き答案の採点実行時の画面です。


スキャナーで読み取った手書き答案のJpeg画像から、大問1の設問(1)なら(1)のみを抽出、一覧表示してイッキに採点。採点記号( 〇・△・× )& 得点付きで元の答案画像に書き戻し、最後に得点合計を自動計算、指定位置に描画して、返却用答案画像(A4サイズに統一/縦・横の指定は可能)を印刷できる無料の手書き答案採点補助プログラムです。

一般的な横書き答案に加え、国語で使用される縦書き答案の採点も可能です。

縦書き答案の採点実行時の画面です。


新教育課程の観点別評価にも対応。もちろん、表計算ソフトを使わずに成績一覧表の作成・印刷・CSVファイルへの出力が可能です(ただし、成績一覧表の出来栄えは、メモ程度)。

画像処理に使用しているPython用OpenCV関連のファイルサイズが巨大ですが、このファイルサイズを許容していただければ、採点現場で十分使えると(複数の高校で使用中)評価していただけました!

もちろん、完全無料。ただし、動作保証は一切ありません。作成者(僕)は開発環境のDelphi(Object Pascal)の大ファンで、この他にも自作のマークシートリーダーなどを開発・このblogの過去記事で公開していますが、学問領域で評価の対象となるようなプログラミングに関しては全くの素人です。ですから、このプログラムのご使用に際しては、あくまでも素人が趣味で作ったものであるということを十分にご理解いただき、ダウンロードから展開・実行までALL自己責任でお願いします(有償販売禁止の他は、それが唯一の使用条件です)。発見できた不具合はすべて改良改善しましたが、取り切れていない未発見の不具合もまだきっとあると思います。それでも、もし、よろしければお使いください。僕の夢のカタチ、Answer Column Reader。

手書き答案採点補助プログラム、名付けて AC_Reader です。

【もくじ】

1.使い方
(1)zipファイルを展開
(2)プログラムを起動
(3)スキャンした答案の画像を準備
(4)採点用画像の準備
(5)解答欄の座標を取得
 ・【座標データを追加したい場合は?】
 ・【字数制限のある解答欄座標の簡単な取得方法は?】
 ・【機械が認識しやすい解答欄】
 ・【生徒の番号・氏名も解答横に表示して採点したい】
(6)採点
 ・【全員正解を入力】
 ・【全員不正解を入力】
 ・【個別に採点】
 ・【次の設問を採点】
 ・【定型文を入力】
 ・【入力した定型文の削除・消去方法】
(7)採点状況の確認
(8)返却用答案の印刷
(9)成績一覧表の作成・印刷
2.まとめ
3.お願いとお断り

1.使い方

もくじへ戻る

(1)zipファイルを展開

ダウンロードしたzipファイルをデスクトップ上に展開します(任意の場所に置いても動作すると思いますが)。PCによっては展開(解凍)に20分程度かかることがあるようです。

もくじへ戻る

(2)プログラムを起動

展開されたフォルダ内に「AC_Reader.exe」があります。これをダブルクリックしてプログラムを起動します。

このアイコンをダブルクリックしてプログラムを起動します


初回起動時には、次のメッセージが表示されると思います。その場合は「詳細情報」(画像中、赤い枠で囲んで示した部分)をクリックします(プログラムの発行元が不明である場合に、Windows のDefender機能である SmartScreen がこの表示を出すそうです。自分の責任で実行すれば、次回からこのメッセージは表示されなくなります)。

「詳細情報」をクリックします。


すると、次の画面が表示されます。「実行」(画像中、赤い枠で囲んで示した部分)をクリックしてプログラムを起動してください。

「実行」をクリックします。


プログラムの起動時に、次のメッセージが表示されます。「はい」・「いいえ」のいずれかを選択してください。

差し支えなければ「はい」を選択してください。


Excelの採点シートを使って処理する場合は、拙作マークシートリーダーとこの手書き答案採点補助プログラムを併用することも可能です(その方法についての説明は、今回は行いません)。

マークシート方式と併用することも可能ですが、今回は「はい」をクリックしてください。


国語の試験では縦書きの解答用紙が使われますので、この手書き答案採点補助プログラムも縦書き答案の採点が出来るよう設計しました。デフォルト設定の答案書式は「横書き」です。国語の縦書き答案を採点したい場合はここで設定画面を開き、縦書きを指定してください。

今回は「いいえ」で先に進みます。


ちなみに「はい」を選んだ場合は・・・

答案の書式を指定できます。


答案の書式の設定変更を起動時に問われなくするよう設定できます。

採点する答案の書式が決まっている場合は「はい」を選択してください。


試験は毎日行われているわけではなく、定期考査として2~3か月に1回実施されるのが普通です。これくらい間が空くと、△の付け方などをどうしても忘れてしまいます。「忘れた!」と毎回のように質問がありましたので、プログラムの起動時にメッセージとして、採点方法を表示することにしました。

特に「△」の入力方法を問われることが多かったです!


この入力方法の案内は、画面右下の「終了」ボタンのとなりにある「入力方法のご案内」ボタンをクリックすれば、いつでも再表示できます。

入力方法はいつでも確認できます。

もくじへ戻る

(3)スキャンした答案の画像を準備

答案の画像は必ず「解像度200dpi程度」でスキャンし、「Jpeg画像として保存」してください。

重要 白黒の二値化画像としてスキャンしないでください。

なお、答案をスキャンする際は、次のことにご注意ください。

・答案が出席番号順に並んでいることを必ず確認してください。
・答案の向きは問いませんが、上下が揃っていることを必ず確認してください。
・試験を欠席した生徒がいる場合は、そこに未使用の解答用紙を挿入しておきます。
・消しゴムの屑等はよく払い落としておきます。
・一度に採点できる枚数は100枚を想定しています。
・答案に折り目がある場合は、なるべく平らになるよう折り戻しておきます。

スキャンした答案の画像は、科目名とクラス・講座名がわかるよう適切な名前をつけたフォルダ内に保存し、このフォルダをAC_Reader.exeがあるフォルダの「ScanData」フォルダにコピーしてください。

重要 スキャンした画像は、必ず「ScanData」フォルダ内にフォルダを作成し、保存してください。

重要 ScanDataフォルダ内のフォルダに階層構造を作らないでください。

よい例:

ScanData¥数学Ⅰ_1A

わるい例:

ScanData¥1年¥数学Ⅰ_1A

もくじへ戻る

(4)採点用画像の準備

上記の手順で、スキャンした答案のJpeg画像を所定の場所に準備したものとして説明します。

プログラムの画面右上にある「画像変換」ボタンをクリックします。

重要 採点用画像には、必ずこの画像変換プログラムが生成したJpeg画像を使ってください。それ以外の方法で作成した画像は使用できません!


次のWindowが開きます。「選択」をクリックしてください。

ScanDataフォルダ内に用意した「答案画像を入れたフォルダ」をクリックして選択します。
練習では予め用意されているSampleフォルダを選択してください。

重要 選択するのは「フォルダ」で、「ファイル」ではありません。

採点したい答案画像のあるフォルダをクリックすればOKです。
(ダブルクリックして開ける必要はありません)

サムネイル表示を見て、画像の回転の有無・回転方向を指定します。Sampleの画像で練習する場合は「なし」を指定してください。

次に画像のリサイズの有無を指定します。複合機のスキャナーを使用し、解像度200dpiでスキャンした画像の場合、80%程度に縮小すると採点しやすいと思います。答案画像をプレビューして縮小率を確認しながら作業することができます。

画像のリサイズ設定を行ったら、次に採点用画像の保存先を指定します。「参照」ボタンをクリックしてください。画像の保存先を選択するWindowが表示されます。

採点用画像の保存先は、ScanDataフォルダ内ではなく、「ProcData」フォルダです。

Procはprocessed(処理済み)の略です。

重要 ProcDataフォルダ以外の場所は、作業フォルダに出来ません!

画像の変換元として選んだScanDataフォルダ内のフォルダと同じ名前のフォルダを、プログラムはProcDataフォルダ内に自動的に作成します。ここでは、この自動的に作成されたSampleフォルダをクリックして選択し、OKをクリックしてください。

フォルダは自動的に作成されたものを選びます。

「変換実行」ボタンをクリックすると採点用にリサイズされた画像が上で指定したフォルダ内に作成されます。この処理はGDI+で書きましたので、それなりに高速だと思いますが、答案の枚数が多く、回転を伴う場合は少し時間がかかります。処理が完了するまでしばらくお待ちください。

この処理では用途の異なる2種類の画像を作成します。一つは採点マークのない各解答欄画像の読み取り元として利用する画像、もう一つは採点マークその他必要事項を上書きした返却用答案画像として利用する画像です。このようにすることで、何度でも採点のやり直しができる仕組みを実現しています。

注意していただきたいのは(めったにないことですが)、採点結果を答案画像に書き戻している最中に何らかの原因でプログラムが落ちた(クラッシュ/フリーズ)場合です。プログラムは採点結果を数値データとしてCSVファイルに書き込むと同時に、採点マークを付けて返却用答案画像にも書き込みます。CSVファイルへのデータの書き込みは一瞬ですが、返却用答案画像への書き込みには少し時間がかかります。したがって、この書き込み処理の最中にプログラムが落ちると、確かに採点した(採点データを保存したCSVファイルが存在する)のに、採点結果が正しく書き込まれていない答案画像が出来てしまうといった現象が起こります(過去1回だけ、この現象を確認しました)。このような場合には、それを発見した時点で採点済みのデータを読み込んで、再度(画像への)「書き込み」処理を実行すれば不具合を解消できます。

変換が終了すると、そのことを知らせるメッセージが表示されます。メッセージのOKをクリックすると注意のメッセージが表示されます。この注意のメッセージを確認した後、「終了」ボタンをクリックして、画像変換処理を終了してください。

終了をクリックして、この窓を閉じます。

メッセージの「OK」をクリックすると表示されるメッセージです。

画像のリサイズを行った場合は、その際設定した縮小率を試験で使用した解答用紙の残部などに必ずメモしてください。複数クラスで様式の異なる解答用紙を使って試験を行い、それぞれに74%、87%など細かな値を指定した場合は2日も経てばかなりの確率でその値を忘れます。この値を忘れた場合には、採点設定作業をすべてやり直すことになります。十分注意してください。

もくじへ戻る

(5)解答欄の座標を取得

次に解答欄の座標を取得します。その際、重大な注意事項があります。

重要 実際に試験で使用した解答用紙の画像を使用する

わるい例:
・輪転機で大量に印刷した解答用紙でなく、PCからプリンターに出力した解答用紙を使用

上のわるい例のように、実際に試験で使用した解答用紙とは異なる印刷環境で作成した解答用紙は、解答欄座標の取得には使用しないでください。見た目はほとんど同じでも、ほんのわずかな印刷位置のずれが採点作業のすべてに悪影響を及ぼします。この点には、どうか十分にご注意願います。

最初に開発したバージョンでは、拙作マークシートリーダーと同じように解答用紙に座標原点とするマーカー画像を設け、OpenCVのテンプレートマッチングの機能を利用して、マーカー画像からの距離で解答欄の座標を記録し、解答欄矩形の選択に利用していましたが、解答欄矩形を自動的に認識する方法を学んでからは、マーカー画像を利用し、手動で一つ一つ解答欄矩形を指定するよりも、解答欄矩形を自動認識して採点対象とする矩形の座標データのみを取捨選択して保存した方が、実際の採点に入るまでの準備作業時間を大幅に短縮できることがわかりました。また、輪転機を使用して印刷した解答用紙自体に解答欄の印刷位置のずれはほとんど生じないことも、マーカー画像を利用した解答欄座標の取得から、解答欄矩形を自動認識する方向へ設計を変更する大きな要因となりました。

以上の理由からご理解いただけると思うのですが、この手書き答案採点補助プログラムで使用する解答用紙は「解答欄の印刷位置がすべて揃っているもの」でなければなりません。

前置きが長くなりましたが、その具体的な方法は次の通りです。

最初に画面右上の「採点作業」ボタンをクリックしてください。


以前に使用した採点設定ファイルが見当たらない場合は、次のメッセージが表示されます。

よく読んで、OKをクリックしてください。


以前に使用した採点設定ファイルがある場合は、次のメッセージが表示されます。


使用する採点作業の入力欄に下の例のように入力します。

例:R06_考査①_物理基礎

前の方が見えませんが・・・

重要 採点作業の名称にはクラス名を入れないでください。

同じ採点作業の設定を複数クラスに適用する際、採点作業名に特定のクラスの名称が入っていると、なんとなく違和感を感じませんか?(僕は違和感を感じました)

このプログラムでは、(同一問題で実施した)試験の答案をクラス・講座毎のフォルダに準備して、同じ(一つの)採点設定をそれぞれのクラス・講座に適用して採点します。したがって、採点作業の名称には「クラス名を入れない」ことが望ましいわけです。※ クラス名が入っていても採点作業に使えないわけではありません。

採点作業名を付けたら、入力欄の右側にある「Auto」ボタンをクリックしてください。

ほんとうは「解答欄矩形の自動選択」のような名称にしたかったのですが、スペースが・・・


次のメッセージが表示されます。よく読んでOKをクリックしてください。

AC_Readerとは別に、解答欄矩形を見分けて自動選択するプログラムが起動します。このプログラムもObject Pascal に埋め込んだ Python Script で Python 用の OpenCV の機能を利用して動作します。

重要 RectangleDetector.exeを直接起動しないでください

重要 矩形検出機能はAC_Readerから呼び出して使ってください

解答欄矩形を認識するプログラムの名称は「Rectangle Detector(長方形検出器)」です。最初に画面左下にある「画像選択」ボタンをクリックしてください。


ここではフォルダではなく、「ファイルを選択」するダイアログボックスが表示されます。どれでもよいのですが、欠席者がいる場合は、解答欄に何も書き込まれていない欠席者分の解答用紙の画像を選択した方が、誤検出は明らかに減ると思います。ファイルを選択したら「開く」ボタンをクリックしてください。

重要 ここではフォルダではなく、ファイルを選択します。

重要 実際の試験で使用した解答用紙の画像で作業します。

練習では、添付したSampleフォルダ内のファイルを選択してください

解答用紙の画像が表示されます。上下のスクロールバーを操作して、図のように解答用紙の解答欄の直線部分とRectangleDetectorの画面枠の二つを見比べやすい位置に画像を上下に動かして、解答用紙が大きく傾いていないことを確認します。

スキャナーによっては、その機材特有の「クセ」のようなものがあり、どれほどきちんと解答用紙をセットしても必ず0.3~0.4°くらい読み取った画像が傾いてしまう場合があります。サービスマンの方に相談したところ、「答案に付着した消しゴムの屑がローラー等に詰まって、読み取り結果に悪影響を及ぼしているのではないか?」との意見をいただき、実際、スキャナーの可動部をきれいに清掃して試したところ、読み取り結果が改善された経験があります。しかし、その後、またすぐにその機材で読み取った画像は同じ方向に傾くようになりましたので、毎回クリーニングする必要があるのかもしれません。ただ、可動部をクリーニングしなくても、ほとんど傾かずに読み取ることもあり、結局、「これは運だ!」と割り切って、プログラム側で傾きがあった場合は修正できるよう、傾き補正の機能を追加しました。

傾き補正の機能を追加する際に気づいたのですが、回転させた画像をさらに回転させると、画像の質が著しく劣化し、これを繰り返すほどに全体がぼやけて、解答の読み取りに支障をきたす恐れがあるように感じました。そこで、画像の初期状態を保存しておき、回転は必ず初期状態のものに対して行うようプログラミングしました。「なぜ、少しずつ連続して回転させることができないのだろう?」と疑問に思われる方もいらっしゃるかもしれませんが、これがその疑問への回答です。

赤線部分を見比べて、画像の回転の要/不要を判断します。


上の画像のような状態であれば、傾きの補正は必要ありません。オプションボタンは「実行」をクリックして選択してください。また、あまりにも小さな矩形は「解答欄ではない」と判断できるよう、矩形の面積閾値を設定してあります。こちらはデフォルト設定700のままでお試しください。

傾きの修正が必要な場合は「試行」を選択し、修正量を確認してください。
修正量を確認後、その値で傾きの補正を「実行」してください。
(「試行」を選択した場合は、最終的なデータの保存ができません)


続けて答案の「横書き・縦書き」を指定します。Sampleは横書き答案ですので、オプションボタンは「横書き」をクリックして選択してください。


ブロックというのは(表現に苦しんだのですが)、「解答欄の集合をブロックとして見分けられるか・どうか」という意味です。下の図のような解答用紙の場合、1ブロックと表現しています。


ちなみに、次のような場合が2ブロックです。ご理解いただけましたでしょうか?


傾きの修正が必要な場合は、次のGUIで操作してください。「傾き修正」に✅を入れて、▲は修正値を増やす(回転方向は時計回り)、▼は修正値を減らす(回転方向は反時計回り)、「適用」は回転の実行、「やり直し」は画像を初期状態に戻します。


解答欄を取得する準備が整ったら、「解答欄取得」ボタンをクリックしてください。


誠に心苦しいのですが、PCによっては初回実行時、Python Engineの初期化に異常に時間がかかることがあります(職場のPCでは4分程度)。自分のPC(Panasonic製 Let’s note CF-QV)では数秒で終了する処理がなんでPCによってはとんでもない時間を要する処理になるのか? その理由は未だにわかりません。

とにかく、マウスカーソルが砂時計?表示になっていればプログラムは正常に機能していると思われますので、5分程度お待ちください。いったんPython Engineの初期化に成功すれば、プログラムを終了しない限り、2回目以降の実行は何の問題もなく、ほんの数秒で解答欄座標の取得が完了するはずです。

参考 横書き答案の場合、解答欄矩形の座標はx軸方向については左から右へ、Y軸方向については上から下へという順番で読み取ります。

参考 縦書き答案の場合、解答欄矩形の座標はx軸方向については右から左へ、Y軸方向については上から下へという順番で読み取ります。

ただし、解答用紙の画像が右肩上がりに傾いていた場合、Y軸(上下)方向の座標の上下関係から、より値の小さな(座標原点0,0は解答用紙画像の左上であるため)上の方をプログラムは先に読み取ってしまいます。そのため、横書き答案であっても解答欄矩形の読み取り順が右から左になる現象が発生します。こうなると解答欄矩形の座標の選択作業が著しく煩雑になってしまいます(解答欄矩形の座標自体は読み取れていますから作業ができないわけではありません)。これを防止するために、最初に答案画像の全てに対し、傾きの修正を行う必要があります。

解答欄座標の取得が完了すると、次の図にあるように解答用紙上に赤い矩形が描画されます。小さくてわかりづらいかもしれませんが、画面右上の解答欄座標の値が表示されている部分で、カーソルがある(カーソルが点滅している位置の)解答欄座標が赤の矩形で示されています。ここから必要な座標と、いらない座標を取捨選択する作業を行ってください。


上の図で示されている矩形(座標)は採点には不要です。このまま無視して次へ進んでも構いませんし、面倒でなければ不要な座標は削除することもできます。


「編集」ボタンをクリックすると、キャプションが「編集中」に変わり、カーソル位置の座標が選択された状態になります。DELキーを押し下げして、不要な座標を削除します。

次の図は(削除作業を行わずに)上の図の状態から↓矢印キーを1回押し下げして、カーソルを2行目に移動させた状態を表しています。不要な解答欄座標の削除作業を行った場合は、自動的にこの状態になります(1行目にあった不要な座標は当然消えています)。

カーソルを下の行へ移動させて、解答欄矩形のみを選択(移動)して行きます。


2行目の座標が示す矩形はまさに解答欄ですから、これは必要な座標ということになります。このような座標は「移動」ボタンをクリックして、必要な座標ばかり集めたメモの方へ移動させます。次の図は2行目の座標を移動させた直後の状態です。

必要な解答欄座標のみを選択します。

下向きの矢印キーを押す。必要な座標であれば「移動」ボタンで下のメモに移動する。この作業を繰り返して採点する順番になるよう、解答欄の座標をすべて取得します。次の図は一通り、解答欄の座標を取得した状態です。


続いて正しく解答欄座標が取得できていることを確認します。上の図の移動済み解答欄座標が表示されているメモ(赤枠内)の先頭の座標データをクリックしてください。メモは必要であれば上にスクロールしてください。メモの先頭の座標データをクリックしたら、答案の画像も上にスクロールしてください。画面は、次の図のようになります。

メモ内のフォーカスがある座標データに該当する矩形が赤枠で示されています。


このまま、下向きの矢印キーを次々に押し下げして、赤枠で示される解答欄矩形が必要数あるか・どうか、及び、採点順に並んでいるか・どうかを確認して行きます。

もくじへ戻る

【座標データを追加したい場合は?】

様々な事情から、座標データを後から追加・変更したい場合もあるかと思います。例えば、次の図のように青枠で囲った解答欄AとBを抱き合わせて採点(両方正解で〇等)したい場合です。

青枠部分を抱き合わせて採点したい場合も当然あるかと思います。


このような場合は、該当の座標データの「末尾」にフォーカスした状態で(=座標データの末尾にカーソルを置いて)、「移動」ボタンの隣にある「追加」ボタンをクリックし、さらにEnterキーを1回押し下げして改行します。次の図は、その状態を示します。

「追加」ボタンのキャプションは「追加中」に変わります。


次に、画面の真ん中よりやや右にある追加ボタンをクリックします。


答案画像の上に赤枠の矩形が表示されます。この矩形を新しく解答欄座標を取得したい解答欄に重なるように移動・変形してください。矩形を移動させたい時は、矩形の上の横線中央よりやや右の位置をポイント(マウスのカーソルを載せる)すると、マウスカーソルが上下左右の白い矢印に変わり、ドラッグアンドドロップできる状態になります。

任意の座標を取得可能です。


抱き合わせて採点したい解答欄を矩形で囲んだら(下の図のような状態)、キャプションが「取得」に変わったボタンをクリックします。すると、ボタンの右側に、現在表示されている矩形の座標が表示されます。同時に、この矩形データはクリップボードにも送信されています。


続けて、右側のメモ内の先ほど改行して空行になっている箇所をクリックしてCtrlキーを押しながらVキーを押す(右クリックして表示されるサブメニューから「貼り付け」を選択)等して、取得した座標データを付け加えます。正しくメモに追加できたら、メモの上の「追加中」ボタンをクリックして、キャプションを「追加」に戻します。

上下の矢印キーを押して、解答欄Aの座標を探し、「追加」ボタンをクリックして、メモを編集可能な状態に変更、データを削除します。削除後、編集が終了したことをPCに伝えるため、「追加中」ボタンをクリックして「追加」に切り替えます。

解答欄Bの座標も、解答欄Aと同様に作業してメモから消去します。

注意 「追加中」状態で作業しないとエラーが発生します!

もくじへ戻る

【字数制限のある解答欄座標の簡単な取得方法は?】

例えば、次のような多数の細かい枠で構成された字数制限のある解答欄がある場合、このまま矩形座標の自動取得処理を実行すると一つ一つのマス目の座標をもれなく取得・表示してしまいます。

解答欄を構成する枠がすべて実線の場合、解答欄座標の取得が煩雑になります。


このような場合は、解答欄を作成する段階で、外枠のみ実線で描き、内部の枠はすべて「点線」で描くようにします。点線は、色が薄く、間隔の狭い、細い点線でなく、次の図に示すように、色が濃く、間隔が広い、太い点線を使用してください。

解答欄内部の枠を「点線」で描くとプログラムは外側の枠のみを解答欄座標として認識します。


実は、最初の段階からこの「字数制限のある解答欄の認識処理をどうするか?」という問題は大変気になっていたのですが、親しい国語の教員が作成した解答用紙をスキャンして、解答欄の座標を自動取得する作業を手伝った際、解答用紙の点線部分をプログラムが認識しないことを偶然発見、大喜びしたというのが本当です。最初から、僕に、そのような知識があったわけではありません。

偶然とは言え、僕の不出来なプログラムの動作を信じて、それでも使いたいと言ってくれた彼女に、心から、ほんとうに、こころから、「ありがとう」です。巡り合ってから、もう、30年になりますが、Sさん、ほんとうに、ありがとう! あなたがいてくれて、ほんとうに、よかった!!

ただし、これは「諸刃の剣」で、何らかの原因で解答欄の枠線の一部が途切れていると、プログラムは正直にその部分は「矩形ではない」と判断して、座標データの取得対象から除外します。ですので、解答用紙を印刷する際は、解答欄が完全に実線で囲まれているか・どうかを、よく確認してから印刷する必要があります。

解答欄の枠線の一部が途切れていると座標を取得できません!

もくじへ戻る

【機械が認識しやすい解答欄】

解答欄を構成する矩形は必要最小限度に留めるのが、解答欄座標を自動認識・取得する作業を効率よく進めるための何よりのポイントです。

解答欄を構成する矩形は必要最小限にしてください。

もくじへ戻る

【生徒の番号・氏名も解答横に表示して採点したい】

重要 横書き答案の採点時のみに利用できる機能です。

こちらは同僚からの要望があって付け加えた機能です。解答用紙の氏名欄の画像を取得して、採点時に該当生徒の解答欄の横(位置の指定も可能)に、試験を受けた生徒の出席番号や氏名を表示できます。「追加」ボタンをクリックして赤枠の矩形を描画・適切な位置へ移動後、解答欄矩形としての「取得」の代わりに、「氏名欄取得」のボタンをクリックして、次の図に示すようなかたちで解答用紙の氏名欄の座標を取得してください。ただし、指定する矩形の高さは、解答用紙の解答欄の高さの最小値を超えないよう、十分注意してください。

重要 「解答欄の高さの最小値を超えない高さ」で範囲指定してください。

座標が空欄でなければ、氏名情報ありとして保存されます。


最後に、取得した解答欄の座標を保存して作業は終了です。画面右にある「保存」ボタンをクリックしてください。


次の確認メッセージが表示されます。

「はい」をクリックして、解答欄座標を保存します。


採点作業名として設定した名称で、イニシャライズファイルが作成されています。この採点作業名をクリックするとダイアログの下のファイル名が採点作業の名称に変化します。この状態で「保存」ボタンをクリックしてください。

採点作業名を設定した際にiniファイルも作成されています。
解答用紙の種類に合致するファイルをクリックして選択・上書き保存します。


次のメッセージが表示されます。「はい」をクリックしてください。

既存のiniファイルに上書きします。


解答欄の数によっては、少し(数秒程度)時間が必要です。保存作業が完了すると次のメッセージが表示されます。このメッセージが表示されるまで、何もしないでそのままお待ちください。


画面右下隅にある「閉じる」ボタンをクリックしてプログラムを終了します。解答欄矩形の座標の候補を表示する上のメモにデータがある場合は、「閉じる」をクリックすると、次の確認メッセージが表示されます。「はい」をクリックしてプログラムを終了させてください。


以上で、解答欄の座標の取得作業は完了です。

もくじへ戻る

(6)採点

解答欄座標取得後、すぐに採点を実施する場合は、タスクバーにAC_Readerが眠っていますので、クリックして起こしてください。そうでない場合は、AC_Readerを起動してください。

解答欄矩形取得直後、AC_Readerはタスクバーに眠っています。
タスクバーにある上のアイコンをクリックしてください。
AC_Readerが目覚めます!


画面の右上にある「採点作業」ボタンをクリックしてください。


次のメッセージが表示されます。既存の採点設定を利用して採点しますので「はい」をクリックしてください。


バルーン型のヒントが表示されます。V マークをクリックして表示される選択肢から採点設定ファイルを選んでください。


採点設定ファイルを選んだ直後の状態です。


画面中央には、次のメッセージが表示されます。OKをクリックするとフォルダの選択ダイアログが表示されます。


採点したいクラスのフォルダを選択してOKをクリックしてください。

採点したいクラスのフォルダを選択して、OKをクリックします。


採点結果を記録したCSVファイル(場所はユーザーに提示しません)がない場合には、次のメッセージが表示されます。


画面は次のようになります。

個人識別情報が保存されているので、番号や氏名も表示されています。


画面上方、中央よりやや右に、どこにもドッキングしないフローティング状態の必要最小限の採点機能をまとめたパネルがあります。このパネルのタイトルバーの部分を左クリックしてドラッグ&ドロップすると任意の位置へ移動できます。採点しやすい位置へ移動してお使いください。

もくじへ戻る

【全員正解を入力】

解答をざっと見て、過半数が正解であるような場合は、全員に正解を入力し、後から不正解の解答のみチェックして、採点を × に変更します。

この設問の得点は2点として、全員に2点を入力します。


ComboBoxの選択肢に「2」を指定して、「入力」ボタンを

採点記号の位置や大きさは「設定」から変更できます。


設定画面から、採点記号の表示位置や大きさなど、各種設定を変更・保存できます。

何も変更せず、デフォルト設定のまま、みなさんお使いのようです。

もくじへ戻る

【全員不正解を入力】

フローティングパネルの得点欄に0を設定して、入力をクリックすれば、全員不正解となります。

0(ゼロ)は〇(まる)と見間違える可能性があるため、
デフォルト設定では、不正解の場合、得点0を表示しません。

もくじへ戻る

【個別に採点】

重要 左手で入力作業、右手は選択作業(クリックに専念)

・正解 〇 を入力

まず、個別に採点する際の正解入力は、次のように行います。

解答欄の中心付近をクリックして、得点に相当する数字キーを押します。


解答欄に採点記号〇と得点が描画されます。

・不正解 × を入力

不正解を入力する場合は、次のように操作してください。

× は「Batsu」だから「B」キーに割り当てました。


もちろん、数字キーの0(ゼロ)でも × を入力できます。ただ、0はちょっと位置が遠い・・・

・部分点あり △ を入力

部分点ありの場合は、採点記号△と部分点を入力します。方法は、次の通りです。

「部分点あり」のフラグは「-」記号の有無です。
プログラムは負の数の入力を部分点ありと判定しています。
(合計点は絶対値で計算するので、問題ありません)
部分点ありの場合、採点記号△と得点を表示

重要 最後に「書込」を忘れずにクリックします。

もくじへ戻る

【次の設問を採点】

右向きの三角マークをクリックすると、次の設問の解答欄が表示されます。

上で解説した手順で、採点を行います。

右側の操作パネルからも同じ操作を実行することができます。

もくじへ戻る

【定型文を入力】

記述式の設問等で「ここまで何点」のような定型文を記録しておいて適宜入力できます。

「設定」をクリックして、「入力定型文の編集」にチェックを入れます。


画面左上に次の表示が出ますので、内容を編集します。「記録」ボタンをクリックすると編集内容が保存されます。保存後、「入力定型文の編集」のチェックを外し、編集欄を非表示にします。


定型文を入力したい設問の解答欄を採点します。採点後、定型文を入力したい箇所の左上隅あたりにマウスのカーソルを持ってきて右クリックします。表示されるサブメニューから「定型文入力」を選択(クリック)してください。

重要 採点しないと定型文入力はできません!

「定型文入力」をクリックします。


編集済みの定型文が指定位置に入力されます。

もくじへ戻る

【入力した定型文の削除・消去方法】

入力済みの定型文を削除・消去するには、まず、定型文を削除・消去したい解答欄の真ん中付近をクリックします。次に、右側のGridコントロールの青く反転表示された数値を消去して、Enterキーを押してください。

もくじへ戻る

(7)採点状況の確認

現在の採点状況を、解答用紙全体の画像を表示して確認することができます。次のように操作してください。

画面右側の中ほどにある「返却答案を表示」をクリックします。画面は現在選択されている生徒の解答用紙が表示されます。画面をスクロールして、採点状況を確認してください。


移動のボタンで、別の生徒の答案も確認することができます。

左のボタンで「一枚前へ」、右のボタンで「次へ」移動します。

もくじへ戻る

(8)返却用答案の印刷

採点が終了したら、返却用の答案を印刷します。まず、画面右下のプリンタの選択肢から、出力先のプリンタを選択します。次に「合計の印刷」の有無を指定します。「有」を選択した場合は、次の案内が表示されます。


印刷は採点終了後、最後に実行するので、採点と印刷の処理をお互いに行ったり来たりすることは「ない」と判断し、印刷実行後はプログラムの終了のみ可能となっています。

「いいえ」をクリックした場合は、採点処理が継続されます。「はい」をクリックした場合は、次の案内が表示されます。

出力するプリンタの確認です。


「はい」を選択すると、次に合計点の印刷処理の案内が表示されます。


フォントサイズは、40~50程度が適切な場合が多いように思います。半角の数字で入力してOKをクリックしてください。


OKをクリックすると、次の案内が表示されます。


OKをクリックして、合計点印刷位置を指定します。


クリックした瞬間に自動計算された合計点が指定位置に表示され、次のメッセージが表示されます。


よろしければ「はい」を、位置の指定をやり直す場合は「いいえ」をクリックします。「いいえ」をクリックした場合は、再度、合計点を印刷する位置の指定をやり直してください。その際、前回に指定した位置にゴーストというか、残像のようなものが残りますが、実際の印刷時にはゴースト・残像は印刷されません。

「はい」をクリックした場合は、次のメッセージが表示されます。


画面右下の「印刷」ボタンをクリックしてください。

バルーンヒントが案内します。


「印刷」をクリックすると、次のメッセージが表示されます。


OKをクリックすると、プリンタの設定画面が表示されます。この画面はお使いのプリンタにより異なりますが、重要なチェックポイントは次の3点です。

重要 印刷する用紙がA4版であることを確認する

重要 印刷用紙の縦・横指定を答案に合わせて指定する

重要 両面印刷は必ずOFFに設定する

設定画面を閉じると、次のメッセージが表示されます。


「はい」をクリックした場合は、全員分の返却用答案がプリンタへ出力され、次のメッセージが表示されます。


「いいえ」をクリックした場合は、次のインプットボックスが表示されます。

答案の通し番号を入力してOKをクリックしてください。
採点対象がクラスであれば、出席番号となります。


OKをクリックするとプリンタへ印刷データを送信後、次のメッセージが表示されます。


「はい」をクリックすると、再びインプットボックスが表示され、引き続き単票の印刷処理が継続して行われます。「いいえ」をクリックした場合は印刷処理を終了します。画面右下の「終了」ボタンをクリックして、プログラムを終了してください。その際、次の案内が表示されます。

「はい」をクリックすると、プログラムが終了します。

もくじへ戻る

(9)成績一覧表の作成・印刷

画面右にある「成績一覧表を作成」の「Excelを使わずに作成します!」をクリックします。


画面は成績一覧表作成モードになります。クラス単位の採点である場合は、学年・クラスを指定(選択)します。

重要 予めsNameフォルダに生徒氏名データを用意しておきます。

重要 講座単位の処理の場合も、講座名等で氏名データを準備しておきます。

重要 氏名データの並び順は、答案の並び順と一致させてください。

クラスを指定する場合は、直接入力してください。


講座を指定する場合は、学年・組は「空欄」のまま、「観点区分入力」に進んでください。

設問毎に「知識・技能」は1、「思考・判断・表現」は2を入力します。


観点別評価の区分を入力後、「保存」をクリックしてください。

保存後、「採点結果表示」をクリックして、採点結果の一覧を表示します。

氏名データは架空のもので、得点はダミーデータです。


学年・組を「空欄」で処理していた場合は、ここで「講座等」の名票を選択します。

氏名データは架空のもので、得点はダミーデータです。


次に、合計点が0の生徒について、欠席者であるか(平均点の計算から除きます)・真に0点であるのかを指定する処理を行います。「欠席者を除外」をチェックしてください。


合計点が0の生徒がいる場合は、次のメッセージが表示されます。

試験を欠席していた場合は「はい」を、0点であった場合は「いいえ」をクリックします。
(ここでは「はい」で処理します)


「再計算」ボタンをクリックして、平均点他の再計算を実行します。


プレビューをチェックして、印刷プレビューを表示します。


プレビューをチェックすると、印刷プレビューとともに、次のメッセージが表示されます。

印刷プレビュー画面(氏名データは架空のもので、得点はダミーデータです)


表示されるメッセージ。


プレビューのチェックを外すと、次のバルーンヒントが印刷ボタンを案内します。


「印刷」ボタンをクリックすると、印刷設定のダイアログが表示されます(ダイアログはプリンタにより異なります)。成績一覧表はデフォルトで「A4・縦置き」印刷に設定されます(この設定を変更することはできません)。


OKをクリックすると、印刷データがプリンタへ送信されます。送信が完了すると、次のメッセージが表示されます。


なお、これとは別に、このプログラム用に作成したExcel Book(添付したマクロ有効テンプレートのコピー)へ採点結果を出力し、成績一覧表及び個人成績票を作成する機能もこのプログラムにはありますが、これに関する説明はまた後日、このblogに掲載できたら・・・とも、考えています。が、ほとんど!!どなたにもお読みいただけないであろうMy blogですので、もしかしたらそれは、はるか未来の話になるかもしれません。

ただ、PCの操作及びExcel Bookの扱いに慣れた方なら、このプログラムに添付したマニュアル(以前のバージョンのものなので画面や内容が現行バージョンと若干異なります)と、マクロ有効のExcel Bookの式とマクロをご覧いただければ、操作方法並びに機能の概要はおわかりいただけるのではないかと考えます。

このExcel Bookに対する出力機能は、(ここに掲載した)成績一覧表を独自に作成する機能をこのプログラムに追加する以前に作成し、実際の試験の採点で何回も活用済みのものですが、こちらも動作保証等は一切ありません。もし、お使いになる場合は自己責任でお願いいたします。

以上で、成績一覧表の印刷は終了です。

もくじへ戻る

2.まとめ

今回、掲載した手書き答案採点補助プログラム(新教育課程観点別評価「知識・技能」及び「思考・判断・表現」の評価に対応)の概要は以下の通りです。

【出来ること】

(1)スキャナーで読み取った答案画像から設問ごとに解答欄を抽出して一括採点。
   ※ 答案画像からの解答欄座標の取得は矩形認識プログラムで(半)自動実行。
(2)解答欄画像の隣に受験者氏名等を表示(予め氏名欄等の読み取り設定が必要です)。
(3)記述式の解答に対する定型文コメントの入力。
(4)採点結果を出力した返却用答案画像の作成と印刷(A4版限定・縦横指定は可能)。
   ※ 得点合計を自動計算、返却用答案の指定位置に印刷可。
   ※ B4やA3の答案画像は、A4サイズに縮小して印刷します。
(5)表計算ソフトを使わずに、成績一覧表(教科担任用)を作成。
(6)成績一覧表データをCSVファイルに出力(観点別評価のうち、2観点の評価に対応)。
(7)拙作マークシートリーダーを利用した試験との併用も可。
   ※ マークシートの読み取りプログラム一式も同梱しています。
(8)PDF化した答案画像をJpeg画像化して採点(添付のPdf2Jpg.exeを使用)。

【出来ないこと】

機械学習による手書き文字の認識にも過去にチャレンジ(〇・× 及びカタカナのアイウエオを判定)したことがあるのですが、どう頑張っても認識率が100%にならない(控えめな表現で9割程度は正しく認識するのですが、解答欄からはみ出した文字や、それは「ア」でなく「つ」と「ノ」でしょ!みたいな文字を構成する部品が極端に離れている字?や、大きく傾いた文字は正しく認識できない)ので、残念ですが、この機能は搭載を見送りました。

〇×記号やカタカナ一文字の認識結果を目視でイチイチ確認するのはどう考えても二度手間です。現時点では、ヒトが行った採点結果を機械にチェックさせる方向で活用した方がいいかもしれません。学習モデルの作成については、Pythonを利用した事例がWeb上に読み切れないほど存在しますが、(僕が実験した範囲では)それらよりMicrosoftのLobeで作成した学習モデルの方が高い認識率を示しました。このことについては当blogの過去記事でその例を幾つか紹介しています。ここで紹介した採点補助プログラムには搭載を見送った自動採点機能ですが、僕の実験結果が何かの参考になれば幸いです。

もくじへ戻る

3.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

もくじへ戻る

マークシートの採点結果通知(個票)及び成績一覧表の作成

ただし、表計算ソフトは使わずに。

【ご案内】

※ 記事中の「マークシートリーダー」とは、僕がDelphiで作ったマークシートリーダーのプログラムのことです。その最新バージョンと、この記事で紹介するプログラム一式を同梱したZipファイルをダウンロードできます。

【はじめに】

マークシートを利用する際、マークをミスなく読み取れたら、次に読み取り結果を適切に処理する作業が待っています。読み取り結果をCSVファイルに出力し、表計算ソフトで作業するのが一般的な処理の流れだと思いますが、表計算ソフトに苦手意識を持つ方が多いのも事実です。

そこでアンケート集計用途ではなく、試験の成績処理用途専用という「但し書き付き」ですが、『表計算ソフトを使わない』・『入力作業は必要最小限度に留める』・『作業はほぼクリックするだけでOK!』というコンセプトを決めて、マークシートリーダーで読み取り処理を行ったマークシート方式試験の採点結果通知シート(=生徒さんに返却する答案)と成績一覧表(教科担任用)の作成にチャレンジしました。

完成までに、ほぼひと月を要しましたが、マークシートリーダーへの「後付け」成績処理プログラムが出来ました(僕自身が採点現場で動作検証を行った範囲では、期待通りに動作しました)。

マークシートリーダー(最新版のVersion 1.1.4を同梱)と合わせて、次のダウンロードリンクからプログラム一式をダウンロードできます。

【マークシートリーダー & 生徒向け採点結果通知シート と 教員用成績一覧表作成プログラムのダウンロード】

※ 僕のマークシートリーダーは、1問1答の採点用途のみに対応(複数マークを抱き合わせて採点する等、複雑な採点方法には対応しておりません)。また、今日(2024年5月30日)気がついた!のですが、マークシート画像に採点結果を出力する機能の一部は、選択肢がゼロ始まり(教科情報用)の場合に対応していません。選択肢がゼロ始まりのマークシートに対応したバージョンは後日掲載します(プログラムは完成していますが、GUIを作り直す必要があります)。

追記 選択肢がゼロ始まり他のマークシートに対応しました!

選択肢がゼロで始まっているマークシート他に対応した採点結果通知シート作成プログラムはこちらからダウンロードできます。プログラム名は「ReportCard.exe」です。簡単な取り扱い説明のPDFをつけてZipファイルとして掲載しています。展開後、上のリンクからダウンロードした exe と入れ替えて(上書きコピー)お使いください。

追記 100選択肢に対応したマークシートリーダー

大語群(番号0~99)に対応した、複数マークの読み取りを可能にしたマークシートリーダーです。複数マーク読み取りに対応した採点結果通知の作成プログラムも同梱しています。

【もくじ】

1.ダウンロードしたプログラムとその高速化について
2.マークシート画像に採点結果を出力
3.成績一覧表も作成
4.使い方
5.まとめ
6.お願いとお断り

1.ダウンロードしたプログラムとその高速化について

今回紹介する採点結果通知シート作成用のプログラム『ReportCard.exe』は単体では動作しません。動作には、僕のマークシートリーダーが作成したCSVファイル等が必要です。また、動作に必要なフォルダ配置その他の動作環境も、僕のマークシートリーダー専用に作成したものをそのまま利用していますので、僕のマークシートリーダー(MS_Reader.exe) が「確実に動作する環境」で実行していただく必要があります。

ここでは採点結果通知シート作成用のプログラム『ReportCard.exe』の動作検証が手軽に行えるよう、Python環境を除いたマークシート読み取りプログラム(最新版Version 1.1.4)に『ReportCard.exe』を同梱する形でダウンロード用zipファイルを作成し、(上に)掲載しています。もちろん、過去記事で紹介しているPython環境を組み込めば(・・・と言っても、ダウンロードして解凍したPython39-32フォルダをMS_Reader.exeがあるフォルダにコピペするだけですが)、マーク読み取り部分は、より一層高速に動作します。

Python環境:Python4Delphiを利用して Object Pascal に埋め込んだ Python Script を実行し、Python用の OpenCV でマークシートのマークの有無、マークした番号を読み取ります。(PCによっては)Python Engine の初期化になぜか?すごく時間がかかることもありますが、1回初期化すれば、どのPCでも大変高速に動作します。拙作マークシートリーダーの動作に必要なライブラリをすべてインストールしたプログラム埋め込み用の Embeddable Python 一式が下記リンク先からダウンロード可能です。

この「採点結果通知シート作成」プログラムも、Python環境があれば自動的にそれを利用して動作するように設計してありますが、テストしてみた結果で率直な感想を言うと、やはり初回起動時の(必須)Python Engine の初期化に(PCによりますが)かなり時間がかかる(数分!)ことがあります。

僕のPC:Panasonic製Let’s Note CF-QV ではそのようなことはまったく起きませんが、職場で使っているPCではそれが必ず起こります。

とにかく Python Engine の初期化に「それなりに時間がかかる」PCでこのプログラムを使う場合は、例えPython環境があっても、起動直後に画面左上の「✅P4D」のチェックを外し、Python環境を利用せずにプログラムを実行していただいた方が良いかもしれません。

【過去記事へのリンクです】

2.マークシート画像に採点結果を出力

採点結果通知シートのイメージは、こんな感じ(確認画面として表示する手続きは作成しましたが、画像データとして保存する手続きは「その必要なし」と考え、作成しなかったので、これは確認用画面のハードコピーです)。

シートの左上部分を切り取り
シートの右下部分(得点合計等はここに表示)


・・・ですので処理は、採点結果を画面に表示 → そのまま印刷という流れになります。採点の計算は一瞬で終わり、採点画面はすぐに作成できるから、データは保存しません(そもそも保存しておいて、何回も利用するようなモノではないと思いますから)。

まず最初に考えたのは(当たり前ですが)、マーク読み取り結果と配点をマークシート画像に出力(〇の場合は配点=得点となります)し、得点を観点別評価とともにシートの余白(設問番号付近)に表示することです。

正答ならば採点マークと配点(=得点)を表示
不正解の場合、採点マークと配点を表示


採点マークのサイズと水平方向の表示位置は微調整が可能です(ただし、調整結果を保存する機能はありません)。

採点結果の表示位置は、負の数で左・正の数で右に微調整可能

ここで、配点に加え、不正解の場合は正解も表示したくなりました。ただ、記号フォントに縦長の楕円はなかった?・・・と思うので、フォントは好みに応じて選択できるよう、思いつくままにいろいろ設定。

カタチ的には「θ」が最もマークの形状に近い気がします。


ふと、思い立って数字も選べるように設定。

「Num」を選択すると正解のマークの上に数字を表示します


あと、新教育課程では、観点別評価が導入されているので、観点別評価の「知識・技能」は K1、「思考・判断・表現」は K2 として評価の分類も出力できるように設定。正解マークと合わせて表示すると、こんな感じです・・・。

自分的には、コレがいちばん気に入りました!

正解マークの番号を、マークすべき場所に数字で表示する


得点合計と観点別評価ごとの得点合計は(デフォルト設定)シート右下に表示します。もちろん、フォントの大きさは任意の値を設定でき、表示位置は水平・垂直両方向に微調整が可能ですが、こちらも調整後の座標を保存することはできません。


フォントの大きさや表示位置の微調整は、凝り始めたらキリがなくなりそうで、それが表計算ソフトに代わる高い敷居となる可能性(=危険性)を感じ、デフォルト設定で(この程度でまぁいいか?)とユーザーに判断してもらえるよう設定値を調整しました。

すべて控えめな数値を設定しました!
足りない場合は、ちょっと増やせばOKかな?

3.成績一覧表も作成

これがないと採点結果を記録簿に転記し(ここで間違いが発生する可能性があります)、電卓をパチパチ叩いて平均点等を計算するか、一歩進んで、プログラムが出力したCSVファイルを表計算ソフトで処理して、成績一覧表を作成しなければなりません。

転記したり、電卓を使うのは昭和のスタイルだし、働き方改革の流れにも逆行します。CSVファイルを自由自在に操れる方なら、拙作マークシートリーダーには、マーク読み取り結果をCSVファイルに出力する機能を付けてありますから、そちらをご利用ください・・・ってことでOKかな?・・・なんだけれど、「表計算はちょっと苦手で」という方も少なくありません。

PCを使って何かの処理を行うこと自体が、手作業で行ってきた作業を効率よく自動化することに他なりませんから、・・・ほんとうのことを言えば、マークシートリーダーに付属の一機能として最初から成績一覧表の作成機能を付けたかったのですが・・・マークシートリーダー開発当初は、何よりもまず、確実にマークを読み取れることが最重要課題で、それが可能になった時点で実はもう僕自身が(精神的に)ヘトヘトになっていて、(読み取り結果をCSVファイルに出力できれば、あとは表計算ソフトで・・・)みたいな思い(と強い思い込み)があり・・・

新教育課程で導入された観点別評価も、プログラミングして処理するより、表計算ソフトで処理した方がずっと簡単そうに思えたし・・・

同僚からの要望に応え、マークシートリーダーとは別に作成した「手書き答案の採点プログラム」と、マークシートによる解答を併用した採点に対応する場合でも、表計算ソフトは便利だったし・・・

このような諸々の理由から先延ばしになっていた成績一覧表の作成でしたが、2024年、冬、ここで一念発起して、マーク読み取り後の処理に表計算ソフトを一切使わず、ソフトウェアの機能として必要な帳票を出力できるプログラムを書くことに決め、ダミーデータを使って動作確認をくり返し、不具合箇所を発見するたびに少しずつ手直しして、実際に使ってみてどうかという段階にたどり着いたのが、まさに今です。

ただし、どちらかと言えば「採点結果通知シートの方が主」で、成績一覧表は「読めればイイ」程度の、言わばメモみたいなもの・・・表計算ソフトが苦手な方でも、CSVファイルに出力された採点結果を表計算ソフトで開き、得点データを他のワークシートへコピペする作業は可能で、それさえ出来ればあとは協働作業で現場はなんとか動く・・・という勝手な理由で作りは大いに簡素化。

様々な理由から、氏名は「最初の3文字のみ表示」することにしました。
罫線も、横一線のみ。

(氏名と成績はダミーデータです)

ほんとにナイよりマシ・・・というレベルで完成。T_T

プログラムは技術的な知識不足から(だと思うのですが)、罫線が上手く描画されたり、(同じプログラムなのに)PCによっては罫線が予定位置に描画されなかったり・・・。この罫線が上手く描ける場合と、描けない場合の違いがいまだによくわからないのですが、次のようにして無理やり解決?(しましたが、最終的に問題のあるコードは全面的に書き直しました)

【罫線描画問題解決用GUI の勇姿】

CheckBoxとButtonを一つずつ用意


(1)設定 → システム → ディスプレイ設定変更画面の表示を1クリックで行えるボタンを作成。非常の場合は、これで画面の拡大率を100%に戻してもらう。拡大率100%なら確実に予定の位置に描画されるハズ。

・・・と、思ったのですが、結論から言うとこれはダメでした!!

その後、奮闘努力して問題を解決 → (3)へ

ディスプレイ設定を呼び出すコードは1行でOK!

procedure TForm1.btnDispSettingClick(Sender: TObject);
begin
  //usesにWinapi.ShellAPIが必要
  ShellExecute(0, 'open', 'ms-settings:display', nil, nil, SW_SHOWNORMAL);
end;

(2)CheckBoxを利用して「罫線を描画しない」設定を用意する。チェックOFFだと・・・

ある意味では、究極ともいえる罫線問題解決方法。
(これは、ほとんどムチャですな・・・)


(3)罫線の描画に使っていたコードそのものを新たに書き直し、TImage の Canvas と TPrinter のCanvas それぞれに罫線を描画するようにしたところ、罫線が予期しない位置に描画されてしまう問題は解決できました。最初に書いたコードで、(PCにより)罫線が正しく描画される場合とされない場合がある、その本当の理由は未だにわかりませんが・・・

4.使い方

使ってくださる方がいるとも思えませんが、使い方のマニュアルは以下の通りです。

(1)プログラムを起動

「MS_Reader.exe」と同じフォルダにある「ReportCard.exe」をダブルクリックしてプログラムを起動します。

次のメッセージが表示された場合は、「詳細情報」(画像中、赤い枠で囲んで示した部分)をクリックします(プログラムの発行元が不明である場合に、Windows のDefender機能である SmartScreen がこの表示を出すそうです。自分の責任で実行すれば、次回からこのメッセージは表示されなくなります)。

「詳細情報」をクリックします。


すると、次の画面が表示されます。「実行」(画像中、赤い枠で囲んで示した部分)をクリックしてプログラムを起動してください。

「実行」をクリックします。

アメリカでは、採点結果を通知する個票のことを、高校段階までは “Report Card” と呼ぶそうです。Python4Delphiを使用していることを考えると、プログラムの名称に漢字を使用することは、極力、避けたいところです(これは、Pathに含まれる全角文字に関連するエラーに、Pythonスクリプトを書いていて、これまでさんざん悩まされた経験から)。

また、当初、アイコンは濃い目にデザインしたのですが、100 が赤だと目に痛い。そう、痛切に感じた経緯があって、通常アリエナイ色の 100点 をモチーフにしたアイコンにしました。Report Card の文字は、ほぼ読めませんが!「枯れ木も山の賑わい」とお考えいただけたら幸いです。

100 という数字さえ読み取れれば、何をするプログラムなのか?
お使いいただけた方には、わかってもらえるんじゃないかと・・・。

(2)「開く」ボタンをクリックして、ProcDataフォルダ内にある採点結果通知シートを作成したいクラス(or 講座)のマークシート画像を保存したフォルダを選択。

Python環境が利用できる場合は、P4Dに自動的にチェックが入ります。
※ Python Engine の初期化に時間がかかるPCでは、起動時にチェックをOFFにしてください。


選択するのは「ファイル」ではなく「フォルダ」です。


(3)採点結果通知シートを新規に作成する(既存の採点作業の設定ファイルがない)場合は、次の表示が出るのでOKをクリックし、設問数を入力して、画面左に表示されるGridコントロールに必要事項を入力します。


設問数を最初に入力します。


次に、作業の「入力」を選択(オプションボタンをクリック)します。


配点は最も多く設定する値をデフォルト配点として指定(入力)します。


正解とするマークの番号を入力します。

最初だけフォーカスを与えるために入力するGridをクリックしてください。


配点を変更する箇所があれば、正解に続けて入力します。
最後に観点別評価の区分を入力します。「知識・技能」は半角数字で 1 を、「思考・判断・表現」は半角数字で 2 を、それぞれ間違えないように入力してください。

m(__)m:「主体的に学習に取り組む態度」の評価は、この採点システムでは行えません。

観点別評価の入力を行っているところ。


全項目の入力が完了したら、入力に間違いがないことを必ず確認してください。もし、誤りがあれば、ここで確実に発見し、訂正しておかないと・・・、後から大変なコトに・・・。

必要事項をすべて入力し、内容を確認したら採点設定を保存します。

「MySettei.csv」が(上で指定した)マークシート画像のあるフォルダに保存されます。


保存が完了すると、次の確認メッセージが表示されます。

(4)採点ボタンをクリックして、採点を実行します。


表示されている画像の座標情報を記録したテンプレートを選択します。
(テンプレートの作成は、マークシートリーダーで実行)

テンプレート名をクリックして、決定ボタンをクリック。


適切な採点オプションを選択します。


「観点含全部」を選択した場合は・・・

採点記号と配点(正解の場合は得点)、観点別評価の区分を設問番号付近に表示
得点合計と観点ごとの得点合計を右下に表示
空欄と不正解の場合は、正解を表示


前述した通り、正解記号は選択肢から選択して指定できます。

Numを指定した場合は、正解マークの番号が表示されます

(5)画像の切り替え

表示している画像の切り替えはボタンクリックで実行できます。

ボタンは左から順に「先頭へ」・「一つ前へ」・「一つ次へ」・「最後へ」

(6)印刷

「印刷」ボタンをクリックして、採点結果通知シートを印刷します。


クリックすると表示されるメッセージに答えて、全員分 or 個別 印刷のいずれかを選択してください。


用紙の縦横指定を間違えないように注意してください。

(7)成績一覧表の作成

最初に「学年」と「クラス」を選択してください。


選択制の授業等、特別な編成(=「講座」と表現)の名票は出席番号順・氏名のみのデータを予めsNameフォルダ内に分かりやすい名前を付けて、CSVファイルで準備してください。

学年・組は空欄のままにして、「講座名票」ボタンをクリック


ファイルの選択ダイアログが表示されるので、予め作成・保存しておいた講座の名票を選んでOKをクリックしてください。採点結果一覧がGridコントロールに表示されます。

得点等はダミーデータです。


続けて、平均点を正しく計算するため、未受験者の処理を行います。「編集」チェックボックスをチェックしてください。


未受験と思われるデータがある場合、次のメッセージが表示されます。

テストを受験しており、採点結果が0点の場合は「いいえ」をクリックしてください。


得点「0」はすべて未受験として処理した場合、採点結果の一覧は次のようになります。

未受験者のデータを空欄に変更。


「再計算」ボタンをクリックして、平均点等を更新します。


続けてプレビューをクリックするよう案内が出ます。
プレビューをクリックして成績一覧表を表示します(設定はA4・縦、50名/枚で、この設定を変更することはできません)。

なお、受験者数が51名以上の場合でも、プレビュー画面には最初の1枚目の成績一覧表が表示されます。また、任意のページをプレビュー画面に表示する機能は、このバージョンにはありません。

印刷されるデータをプレビュー画面で確認してください。


プレビューに問題がなければ、プレビューのチェックをOFFにして(外して)ください。
印刷ボタンがクリックできるようになります。

印刷ボタンをクリックすると、プリンターへデータが送信されます。受験者数が50名を超える場合は、プリンターへのデータ送信後、印刷最終ページが画面に表示されます。

5.まとめ

今回、拙作マークシート・リーダーのCSV出力を利用するかたちで作成したプログラム(新教育課程観点別評価「知識・技能」及び「思考・判断・表現」の評価に対応)の概要は以下の通りです。

(1)表計算ソフトを使わずに、マークシート方式試験の採点結果通知(個票)を作成。
(2)表計算ソフトを使わずに、マークシート方式試験の成績一覧表(教科担任用)を作成。
(3)マークシート方式試験の成績一覧表をCSVファイルに出力。

6.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

マークシートリーダーを教科「情報」用に設定

マークシートリーダー関連の第4回は、ゼロ始まりの選択肢への対応 です。

マークシートの選択肢には「1」始まりと「0」始まりが存在します。教科「情報」の試験で使用されるマークシートは「0」始まりが標準?のようです。そこで自作のマークシートリーダー及びマークシートを、それぞれ選択肢「ゼロ(0)」始まりにも対応できるよう改良しました。

選択肢「ゼロ(0)」始まりに対応したマークシートリーダーはこちらからダウンロードできます。

Version 1.1.1は、選択肢のゼロ始まりに対応していますが、マークシートの種類の表示に誤りがあります。
Version 1.1.2で、マークシートの種類の表示の誤りを修正しました(数学->数学/情報)
上の記事内に、無料で使えるマークシートリーダー(MS_Reader.zip)のダウンロードリンクがあります。
重要 MS_Reader の使用はあくまでも自己責任でお願いします。動作保証は一切ありません!


マークシートの読み取り速度をPython環境を組み込んで高速化します。

Python環境を組み込むとマークシートリーダーをさらに高速化できます。
重要 組み込みPython環境のご使用もあくまでも自己責任でお願いします。動作保証は一切ありません!

【もくじ】

1.教科「情報」用マークシートのダウンロード
2.選択肢ゼロ始まりの設定方法
3.重要!テンプレート作成時の注意事項
4.お願いとお断り

1.教科「情報」用マークシートのダウンロード

教科「情報」用マークシートはこちらからダウンロードできます。


選択肢はゼロ始まりで、1設問あたり16個まで設定可能です。

ゼロ始まりで15まで、選択肢数16の教科「情報」用マークシート(Version 1)。
ダウンロードできるのは、これを改良した Version 2 です。

2.選択肢ゼロ始まりの設定方法

MS_Readerを起動すると、画面上部のパラメータ設定入力用コントロールの左側に、選択肢の開始番号を指定するComboBoxがあります。教科「情報」用のマークシートを読み取る場合は、ここに「0」を指定(∨マークをクリックして選択)してください。

教科「情報」用である場合、選択肢は「0」始まりを指定

3.重要!テンプレート作成時の注意事項

マークシート情報を記録するテンプレートを作成する際には、選択肢の枠幅を間違って設定しないよう、十分注意してください。指定は、次の図のように行ってください。

列枠そのものではなく、設問番号部分は含めずに、選択肢部分のみを指定してください。
指定する際は、左上の「⊥」マークから、右下の「T」マークまでの範囲をドラッグします。


この枠の指定が何を意味するかと言うと、マーク読み取りの際、プログラムはまず、上で指定された範囲の「高さ」を行数で割って1行分を切り出し、次に「幅」を選択肢数で割ってマークを1つずつ切り出します。次の図のようなイメージです。


ですので、マークシートを作成する際は、このことを考慮して、各マークの幅と余白が均等になるように作成します。逆に言えば、各マークを上手く切り出せるように選択肢の枠幅を指定する必要があるわけです。

Wordで作成したマークシートの設問01欄の選択肢番号部分を範囲選択すると、
各マークの幅と余白が均等になっているか、どうか、確認することができます。


プログラムは、この切り出したマークの塗りつぶし面積を計算して、それが最大であるものを「マークあり」と判定しています。

各マーク間の余白も重要です。広すぎても、狭すぎても、判定に影響します。広すぎると計算が遅くなり、塗りつぶし面積の閾値の設定が難しくなります。逆に、狭すぎると大きめにマークされた場合、隣までマークしたことになり、複数マークの判定が出やすくなります。選択肢数が多くなると、どうしても各マーク間の余白は狭くなります。大きめにマークされた場合のことを考え、故意にマーク位置を変えて、どれくらいズレに強いか、試行してみました。

ちゃんと読めています!


上の図にある程度のズレであれば、プログラムは正しくマークを読み取れるようです。

もう少し、ズレ幅を大きくしてみました。

「99」は「複数マークあり」を意味します。


さすがに、ここまでズレると判定に影響します。しかし、完全な誤判定でなく、「複数マークあり」という判定なので、読み取り後のチェックで採点者の目視による判断が求められることになります(私はこの結果を見て、安心して使えると判断しました)。

マークシートの作り方については、MS_Readerの操作・設定マニュアルにも詳しい解説があります。オリジナルのマークシートを作られる際は、どうかそちらもご参照いただけますようお願い致します。

マニュアルはPDFです!

4.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。ここに記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

マークシートリーダーを数学用に設定

マークシートリーダー第3弾!
今回は MS_Readerを数学の試験の採点用途に使用するための設定セット を紹介します。
数学用途での採点は、その解答方法から複数選択肢を抱き合わせて採点する設定が必須となります。
MS_Reader.exe単体では、その実現が困難であるため、マークシートの読み取り結果を出力するエクセル・ブックをこの用途向きに専用プログラムで最適化して利用します。
なお、専用エクセル・ブックは大問6個までの数学採点用途に対応しています。

マークシートリーダー第1回の記事はこちらからどうぞ

上の記事内に、無料で使えるマークシートリーダー(MS_Reader.zip)のダウンロードリンクがあります。
重要 MS_Reader の使用はあくまでも自己責任でお願いします。動作保証は一切ありません!

マークシートリーダー第2回の記事はこちらからどうぞ

Python環境を組み込むとマークシートリーダーをさらに高速化できます。
重要 組み込みPython環境のご使用もあくまでも自己責任でお願いします。動作保証は一切ありません!

【もくじ】

1.数学用設定セットのダウンロード
2.数学用設定セットの使い方
3.お願いとお断り

1.数学用設定セットのダウンロード

数学用設定セットは、数学採点用のExcel Bookのマクロ有効テンプレート、このテンプレートから生成したExcel Bookに対して採点設定を書き込む専用プログラム、数学用マークシートのテンプレート3種類(1枚につき大問3個、各問について25設問ア行~カ行~サ行~タ行~ナ行まで設定可能、選択肢は-、±、0~9、a~dの16選択肢 ⇨ これを2枚、大問6まで使用可能)、A3サイズのマークシート画像をA4横サイズの画像2枚に分割・指定フォルダに保存する専用プログラム、練習用フォルダ(2つ)と練習用画像、各プログラムの使い方のPDFファイル等から出来ています。

【数学用設定セットの内容】

数学用設定セットの内容


数学用設定セットは、こちからからダウンロードしてください。なお、ご使用にあたっては同梱の「必ずお読みください_Math.txt」にあります免責事項への同意が必須となります。

2.数学用設定セットの使い方

プログラムの使用順序は、次の通りです。

  1. MS_Reader.exeのバージョンを確認。必要であれば同梱のVersion 1.1.2を古いMS_Reader.exeに上書きします。
  2. ImageCutter.exe、MathFunctionCreator_2024.exeをMS_Reader.exeがあるフォルダにコピーします。
  3. 同梱の数学用採点シート_2024.xltm(マクロ有効テンプレートファイル)をダブルクリックして生成されるマクロが無効な「.xlsx」ファイルに適切な名前を付け、その拡張子を「.xlsm(マクロ有効Book)」に変えて、MS_Reader.exeがあるフォルダ内のeFileフォルダ内に保存してください。同様に「マークシートのテンプレート」フォルダ内のファイルも全てWordのテンプレートです。ダブルクリックすると新しいWord文書が生成されますので、適切な場所に適切な名前を付けて保存し、ご活用ください。
  4. 保存したExcel Bookに試験の受験者のクラス、番号、氏名、ふりがな、性別、試験の正解となる選択肢の番号、配点、観点別評価を入力し、上書き保存します。
  5. MathFunctionCreator_2024.exeを起動し、4.のExcel Bookに対して、抱き合わせ採点の設定を追加します。⇨ 抱き合わせ採点の設定方法は、同梱の「MathFunctionCreator_2024の使い方.pdf」を参照してください。
  6. 同梱のマークシートのテンプレートから作成したマークシートを印刷、試験(試行)を実施(欠席者がいる場合は未使用のマークシートを適切な位置に挿入する等の事後処理を行い)、スキャナーでスキャンして画像化、MS_Reader.exeがあるフォルダ内のScanDataフォルダ内に適切な名前を付けたフォルダを作成し、そこに保存します。
  7. 使用したマークシートがA3サイズである場合は、ImageCutter.exeを起動してマークシート画像をMS_Readerで読み取り可能なA4横サイズの画像2枚に分割します。分割した画像は、MS_Reader.exeがあるフォルダ内のProcDataフォルダ内に自動的に作成されるフォルダに保存します。⇨ A3判画像の分割方法は、同梱の「ImageCutterの使い方.pdf」を参照してください。
  8. MS_Readerでマークシートを読み取り、読み取り結果のチェックを実行後、結果をCSVファイル、及び5.で抱き合わせ採点を設定済みのExcel Bookに書き込みます。
  9. 読み取り結果を書き込んだExcel Bookを開き、成績一覧表及び採点結果通知用の成績個票を印刷します。
  10. 試験の受験者にマークシート及び成績個票を返却し、マークの読み取り結果と成績を本人が確認(マークシートの画像があるので不正は絶対に不可能であることを受験者に周知した上で、マークシートは返却してもOKですが、必要であれば確認作業後、回収して保管。完全に不要となった時点でシュレッダーにかけて処分してください)。採点結果の訂正が必要な場合は、MS_Readerを再起動・マークシート情報を記録したテンプレートを選択・採点対象のマークシートがあるフォルダを選択すると8.で保存したCSVのデータのデータが表示されるので、必要な個所を訂正し、Excel Bookへ再出力、必要な成績個票を印刷して返却し、再確認作業を行ってください。

3.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。ここに記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

マークシートリーダーをP4Dで高速化

マークシートリーダー第2弾!
今回は Python環境を組み込んで、マークの読み取り速度を高速化 します。
出来る限り丁寧に組み込み方法を説明しますので、どうか最後までお付き合いください。

前回の記事はこちらからどうぞ

前回の記事に、無料で使えるマークシートリーダー(MS_Reader.zip)のダウンロードリンクがあります。
重要 MS_Reader の使用はあくまでも自己責任でお願いします。動作保証は一切ありません!

【追記_P4D環境で読み取り実行時、エラーが発生するときは?】

Python環境を組み込んで、これを利用してマークシートの読み取りを実行する場合、次のエラーが発生することがあります。エラーの内容からは推測すると、エラーはテンプレートマッチングの際に利用するテンプレート画像のサイズに起因して起きているように見えますが、ほんとうの原因は違います。

このマークシートリーダーは、Python環境を利用して動作する際は、マークの有無を読み取るJpeg画像の名称(及びフォルダの階層)が次の規則に従っていることを前提としています。

ProcData\XXX\Sample-01.jpg
ProcData\XXX\Sample-02.jpg
ProcData\XXX\Sample-03.jpg
・・・
ProcData\XXX\Sample-40.jpg
ProcData\XXX\Sample-41.jpg

この命名規則にJpeg画像のファイル名(及びフォルダの階層)が従っていない場合、読み取りエラーが発生します。例えば、次のような場合です。

ProcData\XXX\Sample-01a.jpg
ProcData\XXX\Sample-01b.jpg
ProcData\XXX\Sample-02a.jpg
ProcData\XXX\Sample-02b.jpg
・・・
ProcData\XXX\Sample-40a.jpg
ProcData\XXX\Sample-40b.jpg
ProcData\XXX\Sample-41a.jpg
ProcData\XXX\Sample-41b.jpg

特に数学(や情報)用途で2枚1セットのJpeg画像を処理する際は、注意してください。このエラーを防止するには、ファイルメニューの「1 画像変換」⇨「専用画像を作成」を利用してファイル名が必ず連番になるように読み取り専用Jpeg画像を生成して、この画像に対して、マークの読み取りを実行してください。

以下、発生するエラーメッセージの一覧です。

このメッセージは2回表示されます


なお、Python環境を利用しないモード(P4Dを使用のチェックボックスをOFF:下図右上)であれば、読み取り対象Jpeg画像ファイルの名称は動作に関係しないので(読み取り速度は低下しますが)、読み取り可能です。

画面右上の □ P4Dを使用のチェックを外して、Delphi用のOpenCVで読み取りを実行。
読み取り速度は低下しますが、マークを正しく読み取っています。


【読み取り実行前に、選択肢の始まり番号も指定してください】

選択肢の番号は、デフォルト1始まりに設定してあります。教科「情報」用途で読み取りを実行する場合は、読み取り実行前に、選択肢が「1」始まりであるのか、「0」始まりであるのか、その指定を画面上の設定欄で必ず指定してください。

【もくじ】

1.Python環境を準備する組み込み用Pythonのダウンロードリンクがあります
2.Python環境のドッキング
3.高速化の確認
4.システムにC++ランタイムライブラリがない場合は?
5.Python Engine の初期化の問題?他
6.まとめ
7.お願いとお断り

1.Python環境を準備する

Qiita の記事で「 Embeddable Python 」なるものの存在を知り、ほぼ同時に Delphi に Python のスクリプトを埋め込んで、VCL で GUI を作成、内部的に Python のスクリプトを実行する方法を学びました。

この辺の詳しい経緯は、かなり前に記事として書いた通りです。

2022/01/01
2022/01/02


こうして出来上がった、マークシート読み取りに必要なライブラリだけをインストールした、組み込み用のPython環境の内容は、こんな感じです(組み込み用途に作成した Embeddable Python があるフォルダをコマンドプロンプトで開き、「 Python -m pip list 」コマンドを実行した結果です)

ライブラリの主役は Numpy と OpenCV-Python。
Pillow は、日本語を含む Path を読むためにインストール。


最初に用意した Embeddable Python が14MBくらいで(おー!ちいさい☆)と喜んだけど、上記のライブラリを三つ入れたら 158MB に・・・。

ライブラリを構成しているファイルの依存関係がわかれば、必要ないファイルを消しまくって、もっと小さく出来ると思うのですが・・・、その具体的な方法がわかりません!!

仕方がないので、そのまま組み込み用の「Python39-32」フォルダを作成。

フォルダ名の Python は、「Python関連のフォルダだよ!」ってコトが一目でわかるように工夫(?)しました。その次の 39 はVersion番号、ハイフンで繋いだ 32 は 32bit 用って意味です。

これを前回紹介したマークシートリーダーにドッキングさせます。

展開に少々時間がかかりますが、もし、よかったら使ってください。
MS_Reader 組み込み用 Embeddable Python です。

2.Python環境のドッキング

ダウンロードした「Python39-32.zip」を MS_Reader.exe のあるフォルダにコピー・貼り付け、展開してください。※ 動作確認が完了したら「Python39-32.zip」は削除しても OK です!

【展開前】

MS_Reader.exe とダウンロードした Python39-32.zip を同じ階層に置き、
zipファイルを展開(右クリックして「すべて展開」を選択)してください。
展開にはしばらく(1~2分)時間がかかります。

展開時のPC環境?によっては「ものすごく(20~30分)」時間がかかることが実際にありました!!(原因はわかりませんが、時間がかかるだけで、展開そのものは正しく行われました)

【展開後】

重要 MS_Reader.exe と Python39-32 フォルダは同じ階層に置いてください。

MS_Reader.exe と Python39-32 フォルダは必ず同じ階層に置いてください。


ここで念のため「Python39-32」フォルダの構造を必ず確認してください。

〇:Pathに注目してください。これならOK!

MS_Reader\Python39-32\Lib であり、また、
MS_Reader\Python39-32\Scripts であります。

これはダメです。Pathが二重になってます。

MS_Reader\Python39-32\Python39-32\Lib
MS_Reader\Python39-32\Python39-32\Scripts

上の「ダメな例のようにならない」ようにPython39-32.zipを作成しましたから、大丈夫だと思いますが・・・念のため、必ずご確認いただけますようお願いいたします。

以上が『 ドッキング作業 』です!!

MS_Reader.exe と同じフォルダに、Python39-32.zip をコピペして、展開すれば Python環境のドッキングは完了です。

これを夢見て、ンか月。マジ、挫けそうな時もあった・・・ けど。

MS_Reader.exe をダブルクリックして、マークシートリーダーを起動してみてください。

僕のマークシートリーダーは、自動的に、高速動作モードで、起動します。

3.高速化の確認

Python環境がないと(MS_Reader.exe がある場所に Python39-32 フォルダがない場合)・・・

MS_Reader 起動時、マークシートの読み取りを高速化するP4D(PythonForDelphi)モードは利用できませんが、

Python環境があれば(MS_Reader.exe がある場所に Python39-32 フォルダがある場合)・・・

マークシートの読み取りを高速化するP4D(PythonForDelphi)モードを利用する状態で、MS_Reader は起動します。

当たり前ですが、ダミー(中が空っぽ)の「Python39-32」フォルダを作成し、設定を偽ってMS_Readerを起動しても、メリットは何一つありません!

エラーが2つ出るだけです。

実際に、空の「 Python39-32 」フォルダを作成して実験してみました!


もう一つ。


こんなコトする方は皆無と思いますが。あくまでも、プログラムの動作検証として、ご参考まで。

【動作確認】

前回、設定したテンプレートを利用して動作確認します。

いったん、「P4Dを使用」のチェックを外して読み取りを実行します。前回試行した3列25行8選択肢の1枚あたり600マークあるシート3枚の読み取りにかかる時間は・・・


1枚0.805秒で読んでます(PC環境により、数値は当然異なります)が・・・

「P4Dを使用」のチェックを ON にして再び読み取りを実行します。私の PC での結果は・・・


1枚0.245秒強で読みました。

これが速度的に「はやい」か・どうか、このソフトウェアをお使いいただく方により、その判断基準は異なりますから、その思い(感じ方)は違って当然ですが、Python環境を利用しない場合に比較して、Python環境を組み込み、これを利用した場合は(PC環境により、その数値は悉く異なると思われますが)マークの読み取り速度は間違いなく高速化されるはずです(僕の環境では、「それがない」場合に比較して、「それがある」場合は3.3倍速で動作しました)。

ただ、Python環境を組み込んだ場合、プログラム全体の大きさは、12倍以上に巨大化します・・・

プログラムサイズを選ぶか、動作速度を優先するか、
ご使用目的、お使いのPC環境に合わせて選択していただけたら幸いです。

僕は・・・

今日の空みたいな・・・

プログラムを書きたかった・・・だけです *(^_^)*♪

僕が、この世から消えたあとも、動く。

いつか、夢みたとおりの・・・ プログラムを。

だいすきな・・・

大好きな Delphi と・・・

僕の Object Pascal で。

4.システムに Visual C++ランタイムライブラリがない場合は?

お使いのシステムに Visual C++ランタイムライブラリがインストールされていない場合は、MS_Reader 起動時に次のエラーが発生します。

『アプリケーションを正しく初期化できませんでした(0xc0150002)。「OK」をクリックしてアプリケーションを終了してください。』

英文の場合もあるようです。

PCの解像度の関係だと思うのですが、画像がボケていてごめんなさい!


このエラーが発生する原因を調べてみたところ、組み込みPython環境内にある「Python39.dll」が Visual C++ランタイムライブラリを必要とするようで、これがシステムにない場合は、プログラム起動時にバックグラウンドで行っているPython Engine の初期化に失敗して、上記のエラーメッセージが表示されることがわかりました。

お使いのPCで、Visual C++ ランタイム ライブラリのインストール状況を確認するには、[スタート] ボタンを右クリックし、「ファイル名を指定して実行」をクリックして、appwiz.cpl と入力して[Enter]を押します。Python環境を組み込んだ MS_Reader が動作する環境であれば、システムにインストールされている Microsoft Visual C++ ランタイム ライブラリが以下のように表示されるはずです。

現在、私のシステム(Windows 11 Pro 23H2)にインストールされているC++ランタイムライブラリの一覧。
もちろん、このシステムでPython環境を組み込んだマークシートリーダーが正常に動作しています。


システム内で起きていた別のエラーを解決するために、2023年12月上旬に工場出荷状態に戻すリカバリ作業を行いました。同時にOSを最新のバージョンに更新しました。それ以前のシステムの状態は次の通りです(OS のバージョンは 22H2)。※ 私のPCでの話です。

現在の状況とは異なっています。
この状態でもPython環境を組み込んだマークシートリーダーは正常に動作していました。


エラーを解決するには、Visual C++ランタイムライブラリをインストールすればいいわけですが、上の例のように Visual C++ ランタイムはたくさんあるので、手動でひとつひとつダウンロードしてインストールするより、Visual C++ ランタイムインストーラーを使って全ての Visual C++ ランタイムを一括インストールする方が簡単です。

システムをリカバリする前は、次のようにして Visual C++ ランタイムをインストールしていました。

【ご注意願います!】
ここで紹介する方法で Visual C++ ランタイムをインストールする場合、他のプログラムの実行環境との整合性は、一切保証できません。また、最悪の場合、Windowsが起動しなくなるトラブルが発生することも十分に考えられます。インストール作業の全てが自己責任であることを十分ご理解の上、重大な問題が発生した場合は元の環境に戻せるよう、システムのバックアップを取る・現在の設定をメモに記録する等、不具合の発生に備え、必要かつ十分な準備を整えた上で、Visual C++ ランタイムのインストールを行ってください。

以下のサイトから「Visual C++ v56.exe」をダウンロードしてインストール(私の環境にインストールする分には、なんの問題も起きませんでした。もちろん、マークシートリーダーも問題なく起動し、安定動作しました)。

Visual C++ Runtime Installer (All-In-One) v56

https://www.majorgeeks.com/files/details/visual_c_runtime_installer.html

こちらのWebサイトでも(次のリンク先Webページの下の方で)、このインストーラが紹介されています。

Microsoft Visual C ++ 再頒布可能ファイルを削除して再インストールする方法

https://www.autodesk.co.jp/support/technical/article/caas/sfdcarticles/sfdcarticles/JPN/How-to-remove-and-reinstall-Microsoft-Visual-C-Runtime-Libraries.html

インストーラーを立ち上げると、本当にインストールするかどうかを「YES」か「No」かで尋ねられるので、インストールする場合は「Y」をタイプします。その後はPCの画面に表示される英文の指示にしたがって操作してください。

ここから先は、上記のインストーラーを用いて Visual C++ ランタイムをインストールした際、私が実際に経験したトラブル?です(最終的にインストールは成功しました)。

お決まりのUAC起動後(PCの設定によっては)管理者ID 及びパスワードの入力が求められますが、これを入力すると、そのままPCがフリーズしたような状態になり、数分待機しても進展が見られないので、いったん作業を Ctrl+Alt+Delete でキャンセルし、再度、「Visual C++ v56.exe」を起動して Visual C++ ランタイムのインストール作業を実行、今度はトラブルなくインストールに成功する事例です。これは「ある特定のAD環境下にあるPCのすべてに共通して見られた」現象です。現在もその原因はわかりませんが、ご参考まで。

また、システムの状態によっては(現在システムにあるランタイムをアンインストールしているのか?)複数回(と言っても最高2回ですが)、再起動を求められることも(何度も)経験しました。

C++ランタイムライブラリのインストールについて、経験を加味して私がわかるのはここまでです(実は、何もわかってないのとイコールなのですが)。これ以外のエラーメッセージが表示されてインストーラーが起動しない場合も、もしかしたらあり得るかもしれません。大変恐縮ですが、そのような場合は原因の究明を含めて、自己責任でご対応ください。

5.Python Engine の初期化の問題?他

MS_Reader では、マーク読み取り時の体感速度を上げるため、FormCreate時にバックグラウンドで Python Engine の初期化を行っています。MS_Reader.exe のあるフォルダに小さなマークシートの画像とマーカー画像があるのにお気づきになった方がいらっしゃるかもしれません。これは Python Engine 初期化用に用意した画像です。

Python Engine 初期化用の画像をリソースに埋め込み、もし、それがない場合は再生して、
プログラム起動時に Python Engine の初期化が必ず行われるようにしています。


この初期化を「するか・しないか」で、MS_Reader 起動後、初めてマークを「読む」ボタンをクリックした際のプログラムの挙動がまるで違ったものになります。初期化を行った場合は、ごくスムーズにマーク読み取りが始まるのに対し、行わなかった場合は PC が一瞬フリーズしたような状態になり、その後、息を吹き返すかのようにマークの読み取りが始まります。

Python Engine の初期化コードです。

  AppDataDir:=ExtractFilePath(Application.ExeName)+'Python39-32';

  if DirectoryExists(AppDataDir) then
  begin
    //フォルダが存在したときの処理
    CheckPython.Enabled:=True;
    CheckPython.Checked:=True;
    PythonEngine1.AutoLoad:=True;
    PythonEngine1.IO:=PythonGUIInputOutput1;
    PythonEngine1.DllPath:=AppDataDir;
    PythonEngine1.SetPythonHome(PythonEngine1.DllPath);
    PythonEngine1.LoadDll;
    PythonDelphiVar1.Engine:=PythonEngine1;
    PythonDelphiVar1.VarName:=AnsiString('var1');
    PythonEngine1.Py_Initialize;
    //イニシャライズされたことを記憶
    P4D_ini:=True;
  end else begin
    CheckPython.Checked:=False;
    CheckPython.Enabled:=False;
    PythonEngine1.AutoLoad:=False;
    P4D_ini:=False;
  end;

(どこに問題があるのでしょうか?)

PC によっては、この Python Engine の初期化に非常に長い時間を要することがあるようです(エラーメッセージは出ません。この沈黙の時間が終わった後、プログラムは問題なく動作します)。偶然、ある PC でこの現象に巡り合い、あわてて時間を計ってみたところ、その PC では初期化に4分必要でした! なぜ、このような現象が発生するのか、その理由がわからないのですが、「そのようなことがある」ことだけは経験的に明らかですので、ここに書いておくことにしました。

また、マーク読み取り開始時に、マーカー画像の位置をテンプレートマッチングで確認して、それが「本当に見えている」ことをユーザーに明示的に知らせていますが、ここでもその処理に少し時間が必要なことがあります。私のPCでも、この現象は「起きたり・起きなかったり」するような気が・・・。エラーが出るわけでもなく、ただ・・・「ん?」みたいな時間があるだけなのですが・・・。こちらもその原因がよくわかりません。

以上が、現象としてはわかっているのですが、原因が解明できていないPython環境を使う上での問題点です。

それから、私の想定外の操作が行われた場合、メモリーリークが起きる可能性があります。Python環境をドッキングさせた当初は、このメモリーリークにかなり悩まされました。どう頑張っても小さなメモリーリークが発生するのを取り切れず、( Python環境はそういうもの? )と割り切ってしまおうかと思ったこともあったくらいです。

そのたびに思い直し、メモリーリークが発生する原因を突き止めて対応することを繰り返しました。なので、私が想定した操作範囲内でのメモリーリークは全て取り切れたと思います。が、もし、それが発生した場合は、その発生を知らせるメッセージがプログラム終了直後に表示されます( FormCreate時に実行されるコードの中にメモリーリークがあれば検出するコードを残してあります)。

  //メモリーリークがあれば検出
  ReportMemoryLeaksOnShutdown:=True;
メモリーリークが起きたことを伝えるメッセージ
(上の例のメモリーリークは故意に発生させたものです)

6.まとめ

(1)Python環境を利用するとマークシートリーダーは高速化できる。
(2)高速化できるかわりに、プログラム全体のサイズは大きくなる。
(3)原因不明のフリーズのような現象が発生することがある。

7.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。ここに記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

マークシートリーダー

自分的に必要と思った機能は全部搭載しました・・・が、
プロが作った有償販売できるレベルのソフトウェアではありません。
見た目も、使い勝手も、よくないと思います。
もちろん、無料でお使いただけますが、サポートも、動作保証もありません。
ダウンロードから設定まで、ALL自己責任でお願いします。

快適と感じる速度で動作させるには、かなり高性能なCPU搭載のマシンが必要です。
私のプログラミング技術が足りない部分を、CPUパワーでカバーしてもらってます。
マシンによっては、読み取り結果のチェック等がかなりトロいかもですが・・・

それでも、もし、よかったら使ってください。
Delphiで作ったマークシートリーダーです。


参考 後日、別途ご案内するPython環境を用意していただくと、より高速に動作します!
参考 Python環境で動かす場合、Python Engineの初期化に4~5分かかることがあります・・・

ここで紹介しているマークシートリーダーを用いて読み取った結果をCSVファイルに出力し、これをもとに「採点結果を試験の受験者に通知するシート」及び「試験の成績一覧表」を(表計算ソフトを使わずに)作成できるプログラムです。次のリンク先からダウンロードできます。

リンク先からダウンロードできるマークシートリーダーは、消音機能を追加したバージョンアップ版です。

【使い方のご案内】

1.デスクトップにMS_Reader.zipを展開(解凍)
2.高解像度ディスプレイへの対応
3.マークシート画像の読み取り準備
4.テンプレートを作成
5.マークの読み取りを実行
6.読み取り結果のチェック
7.CSVファイルへの書き出し
8.Excel Book の準備作業
9.Excel Book への書き出し
10.マークシート印刷用紙について
11.まとめ
12.お願いとお断り

どんな環境でも、100%動作する保証はできません・・・が、
私と同じ環境・条件を揃えていただければ、きっと動くと思います。

使用したPC及びOS、開発環境は、次の通りです。

・プロセッサ 11th Gen Intel(R) Core(TM) i7-1185G7 3.00 GHz
・実装 RAM 32.0 GB

・Windows 11 Pro 64ビット版
・バージョン 23H2
・OS ビルド 22631.2861

・Embarcadero® Delphi 12 バージョン 29.0.50491.5718

・設計時の画面解像度は「1366 × 768」です。これ以上の解像度でお使いください。

使い方をなるべく丁寧に説明しますので(マニュアルも同梱してありますが)、まず、ここに書かれている順番で、一通り操作してみていただけたら幸いです。

1.デスクトップにMS_Reader.zipを展開(解凍)

ダウンロードした MS_Reader.zip をお使いのPCのデスクトップにコピペして右クリックするとサブメニューが表示されます。この中の「すべて展開」をクリックしてください。

デスクトップに MS_Reader.zip を展開します。


無事、展開に成功したら、MS_Readerフォルダをダブルクリックして開きます。

フォルダ内に展開されたファイルの中に MS_Reader.exe があります。これをダブルクリックしてマークシートリーダーを起動します。


次のメッセージが表示された場合は、「詳細情報」(画像中、赤い枠で囲んで示した部分)をクリックします(プログラムの発行元が不明である場合に、Windows のDefender機能である SmartScreen がこの表示を出すそうです。自分の責任で実行すれば、次回からこのメッセージは表示されなくなります)。

「詳細情報」をクリックします。


すると、次の画面が表示されます。「実行」(画像中、赤い枠で囲んで示した部分)をクリックしてMS_Readerを起動してください。

「実行」をクリックします。

2.高解像度ディスプレイへの対応

高解像度ディスプレイをお使いの場合の対応方法です。高解像度ディスプレイをお使いの場合、設定から「システム」⇨「ディスプレイ」と順にクリックすると、次のように表示されると思います。

拡大縮小に「150~200」という値が設定されていれば、高解像度ディスプレイです。


この場合、起動したマークシートリーダーの画面が小さくて見えにくいと感じることがあるかもしれません。その場合は、次のように操作してください。

MS_Reader.exe を右クリックして、表示されるサブメニューのプロパティをクリックします。

MS_Reader.exe のプロパティを表示します。


「互換性」タブをクリックします。


高DPI設定の変更をクリックします。


「高いDPIスケールの動作を上書きします。」にチェックを入れて、「拡大縮小の実行元:」は「システム」をComboBoxの選択肢から選択して指定。OKボタンをクリックします。


続けて「適用」⇨「OK」とクリックして設定は終了です。これで画面が見やすい大きさで表示されるようになります。

3.マークシート画像の読み取り準備

デスクトップに展開した MS_Reader フォルダ内に「ScanData」フォルダがあります。この中に練習用のサンプル画像が2種類(解像度150dpiと200dpi)入っています。この画像を用いて説明します。

重要 マークシートは、解像度150~200dpiでスキャンしてください。

重要 1回の操作で読み取り可能な枚数は最大99枚です。

MS_Reader.exe をダブルクリックしてマークシートリーダーを起動したら、画面左上の「画像変換」をクリックし、表示されるメニューの「専用画像を作成」をクリックします。


画像変換用のWindowが表示されたら、画面右上の「選択」ボタンをクリックします。


「フォルダの選択」ダイアログが表示されます。ここでは「Scanner_A」フォルダを選択します。フォルダ名をクリックして、下のFolder欄に「Scanner_A」と表示されたことを確認し、「OK」をクリックします。

スキャンしたマークシート画像は「ScanData」内に適切な名前を付けたフォルダを作成し、必ずその中に保存してください!

重要 フォルダ名にハイフン(-)を使わないでください。

参考 フォルダ名には、文字の他、アンダースコア(_)が使用できます。

注意してください。選択するのは「フォルダ」で、「ファイル」ではありません。
(Scanner_Aをダブルクリックして開いても何も表示されません)


画面は、次のようになります。赤い枠で囲んだ部分にマークシート画像のサムネイルが表示されます。回転の必要性の有無と回転方向を確認してください。


この場合は、回転の必要性「有り」で、回転方向は左90°です。これを「画像の回転」のオプションボタンをクリックして指定します。

左90°のオプションボタンをクリックします。


必要であれば、次に画像のリサイズ指定を行います。リサイズを指定「する・しない」の判定基準は、スキャナーでマークシート画像をスキャンした際の解像度の数値で判断してください。

「Scanner_A」フォルダ内のマークシート画像は、ScanSnap iX1500 のノーマルモードでスキャンした画像で、その解像度は 150dpi です。この場合は、ちょうどよい大きさでマークシート画像が表示されますので、画像をリサイズする必要はありません。

重要 解像度150dpi ・A4横置きの場合、リサイズは必要ありません!

重要 解像度200dpi ・A4横置き・解答マーク欄4列の場合、80%の大きさにリサイズしてください。読み取り後のチェックまで含めて、作業しやすくなります。

マークシート画像の読み取り解像度が 200dpi でも、マークシートがA4横置き、解答マーク欄の列数が3列の場合、リサイズは必要ありません

また、A4以外の大きさのマークシートは使ったことがありません!
(用紙の左上にマーカー画像■■■を入れ、その他はここでダウンロードできるサンプルと同様に作成していただければ、用紙サイズに関係なく動作すると思いますが、試行したことがありませんので確かなことは言えません。ただ、画像のサイズが大きくなればなるほど、動作速度は間違いなく低下します。また、複合機のスキャナーを用いて、マークシートを画像化する際も、B4やA3の大きさだと私が使用している機材ではメモリがいっぱいになるのでしょうか? 30枚程度読み込んだあたりで一旦動作が停止します。数百枚単位での読み取りにはそれなりに時間がかかります。そのような理由から、マークシートに使う紙の大きさはA4サイズ以下が適切だと思います。)

参考:プログラムを書いた本人が言うのもナンですが、自動でのリサイズはおまけ程度にお考えください。
ScanDataフォルダのScanner_Bフォルダに保存されたサンプル画像の大きさは、2338 × 1653
これを自動リサイズオプションボタンを指定して、変換してみます。
ProcDataフォルダのScanner_Bフォルダに保存されたサンプル画像の大きさは、1760 × 1248
いちおう、これでマークシート画像が横方向のはみ出し「なし」で表示されました。

重要 画像のリサイズの有無を必ずメモ(記録)してください!

⇨ 複数クラスのマークシート読み取り時に、同じ設定を適用する必要があります。

重要 大きな解像度の画像を扱う場合、動作速度が大幅に低下します!

回転の有無と方向、リサイズの有無を指定したら、画面中央右にある「参照」ボタンをクリックして、保存先のフォルダを選択します。


「フォルダの選択」ダイアログが開きます。Pathを見ると「ProcData」フォルダが指定されていることがわかると思います。なお、Procは「Processed(加工済み)」という意味です。

プログラムは「ScanData」フォルダで指定したフォルダと同名のフォルダを「ProcData」フォルダに自動作成します。この自動作成されたフォルダをクリックして選択します(しつこいようですが、選択するのは「フォルダ」で、「ファイル」ではありません)。下のFolder欄に「Scanner_A」と表示されたことを確認し、「OK」をクリックします。

読み取り用のマークシート画像は、必ず「ProcData」内の自動作成されたフォルダに保存してください!

重要 ProcData以外のフォルダには画像を保存しないでください。

読み取り用画像を保存するフォルダは自動で作成されます!
(自動作成されたフォルダをクリックして選択してください)


「変換実行」をクリックします。

回転とリサイズの有無を指定して「変換実行」をクリック!


次に表示される案内メッセージには「いいえ」を選択してください。


このマークシートリーダーとは別に、手書き答案の採点プログラムを作成しました(準備が整い次第、公開する予定です)。このマークシートリーダーは、そちらと連動しての動作も可能な設計にしてあるため、このメッセージが表示されます。

画像の変換が完了すると、メッセージが表示されますので、OKをクリックします。


変換された読み取り専用画像のサムネイルが表示されます。作成された読み取り用の画像ファイルには連番の名前が自動的に付きます(自動生成されたファイル名は変更しないでください)。

重要 Python環境を利用する場合はファイル名は必ず連番にしてください。

画像処理のアルゴリズムは、GDI+を利用しています。画像の回転とリサイズが伴う場合は、変換に時間がかかります。処理が完了するまでお待ちください。

(後日、別途ご案内する予定の)手書き答案の採点プログラムと併用する場合は、採点やり直しのために必要な画像もここで作成します(Loopが二重にまわり、時間も2倍かかります)。

クラス別に処理する場合は、「画面の初期化」ボタンをクリックします。
変換元フォルダの選択から、画像の変換処理を再実行できます。

画像の変換処理が完了したら、「終了」ボタンをクリックして、この画面を閉じます。

参考:画像を変換する理由は以下の3つです!
(1)Jpeg画像のサイズを最適化するため(全体が画面内に収まるようリサイズしてください)。
(2)画像の名前が連番になるよう、自動的にリネームするため。
(3)証拠画像としてのオリジナルを残したまま、読み取りに最適な大きさの画像を生成するため。

4.テンプレートを作成

次に、マークシートの情報を記録した読み取り用のテンプレートを作成します。これを作成することにより、同じ採点を複数クラスに対して実行したり、設定(縮小処理の有無を含む)が同じマークシートを異なる考査での使いまわしが可能となる・・・

・・・ように設計したのですが、実際には使いまわしがなんとなく不安なので、考査毎にテンプレートを再生成して運用しています。ですので、同じ設定(大きさ)のマークシート画像の情報を記録したテンプレートの使いまわしが可能か・どうか、これについては未確認です。

「確実なマークシート読み取りを実行する」ためには、お手数をおかけしますが、試験ごとに使用したマークシートのテンプレートを作成していただくのが最良の方法であると思います。

メニューの「2 テンプレート」をクリックして表示されるサブメニューの「テンプレートの新規登録」をクリックしてください。別のWindowが開きます。


画面右上の「取得」ボタンをクリックします。


今度は「ファイルを選択」するダイアログが表示されます。任意のマークシート画像を選んでください(1番のファイルを選ぶ方が多いのではないでしょうか?)。ファイルをクリックしてファイル名を取得し、「開く」をクリックします。

マークシート画像のサムネイルをクリックするとファイル名が取得できます。


画面は次のようになります。

このプログラムでは、マーカー(特徴点)画像を利用してマークシートのマーク位置を計算しています。ですので、このプログラムで処理するマークシートには必ずマーカー(特徴点)画像が必要です。

重要 マークシート左上にマーカー画像(■■■)を必ず用意します。

重要 マーカー画像は、マークシート1枚に1つだけ用意します。

画面右の操作パネル上段にある「マーカー」オプションボタンをクリックして選択状態にします。

「選択対象」の「マーカー」オプションボタンをクリックしてください。


マークシートの画像が拡大表示され、マウスのカーソルが大きな「+」になります。

マーカー画像の「左上」をクリックし、ボタンを押したまま「右下」へドラッグしてください。画像上には点線のラバーバンドが表示されます。

マーカー画像の左上を左クリックして、マウスの左ボタンを押したまま、マーカー画像の右下へドラッグ。
点線のラバーバンドでマーカー画像が囲まれます。


ドラッグ中の画像です(わかりやすさのため、マーカー画像より大きめにドラッグしています)。

黒点線がラバーバンドを示します。


マーカー画像の座標を正しく取得できる例です。

マーカー画像とラバーバンドがぴったり重なるようドラッグしてください。


マウスの左ボタンから指を離すと、取得できたマーカー画像が画面右側に表示されます。

数値は、画像左上からの距離です。

マークの読み取り時、プログラムは、コンピュータの眼である「OpenCV」のテンプレートマッチングの機能を利用して、まず、最初にマークシート画像中にあるこのマーカー(特徴点)画像を探し出します(これはマークシート画像1枚1枚について必ず行います)。

次に、マーカー(特徴点)画像左上隅を原点(0,0)として、テンプレートに記録されたマーク欄の座標からマーク一つ一つの位置を割り出して、これを切り抜いて画像化(正確に言うと、マークの切り抜き処理前に、ボカシ・二値化・白黒反転の各処理を行い、マークの切り抜き後に白面積計算処理を行って)、マークの有無を判定しています。

この方式の利点は、印刷そのものが左右にズレでも、マーカー画像と解答欄の相対的な位置関係は一定で変わりませんから、印刷がズレすぎて解答欄が印刷されなかった場合以外は、必ずマークの位置を探し出せる(=マークの有無を判定できる)ことです。

事実、輪転機で印刷(非推奨ですが!)して、チェックから漏れた(チェックしなかった?)、正しい位置から印刷が5cmくらいズレたマークシートも、このプログラムでなんの問題もなく読み取れました・・・。印刷のズレを申告せず、そのまま解答して提出する受験者も受験者ですが・・・。A4横・4列のシートで、解答には3列めまでしか使わなかったから「4列めはなくてもOK! 大丈夫」と思ったのでしょうか? それともただ単にめんどくさかったのでしょうか? たぶん、後者だと思いますが・・・

次は、そのテンプレートマッチングの機能をテストします。画面右にある「マーカー画像の読み取りテスト」ボタンをクリックしてください。テンプレートマッチングが正しく実行されると、マーカー(特徴点)画像が太い赤枠で囲まれます。


表示されるメッセージをお読みいただき、「OK」をクリックしてメッセージを閉じてください。


結果が良好であれば「選択対象」グループの「解答欄」をクリックします。


次に、マークシートのマーク(解答)欄の「行数」と「列数」及び「選択肢の数」を指定します。


マークシートの列数・行数・選択肢数の数え方は次の通りです(Scanner_Aフォルダにあるマークシート画像は、A4横置き・3列・25行・8選択肢の形式です)。


ですので、これを次のように設定します。


ComboBox に正しく設定を入力したら、その下の「採点方法の設定」の座標「1列」のオプションボタンをクリックして選択状態にします。マウスのカーソルが大きな「+」になります。


第1列目のマーク(解答)欄の座標を取得します。マーカー(特徴点)画像の時と同様、第1列の枠のうち、設問番号欄の矩形を除いた選択肢のマークが印刷されている欄の矩形の左上隅を(左)クリックして、そのままボタンを離さずに、枠の右下隅へドラッグします。この作業は正確に、慎重に行ってください。この作業の良し悪しでマークの読み取りの可否が決まります。

極めて重要 設問番号欄を含めて指定してはいけません!

極めて重要 指定するのはマーク欄のみ!

プログラムは、ここで取得した座標値(矩形の高さ)を行数で割り算して列を設問毎1行ずつに切り出し、さらに切り出した1行を選択肢数で割って1つ1つのマークを切り出し、その塗りつぶし面積を計算して、マークの有無を判定しています。

マーク(解答)欄の枠線と、表示されるラバーバンドがぴったり重なるようにドラッグしてください。

※ 下図は2つともドラッグ直後の結果を示しています(〇はドラッグ開始点と終了点です)。

マーク欄第1列めの左上隅を(左)クリックしてそのまま指を離さずに右下隅へドラッグ


ドラッグ中は、黒点線のラバーバンドが表示されます。これを目安に位置決めを行ってください、

画像中の〇印の位置までドラッグします。


指を離すと、ドラッグした範囲が赤い矩形で囲まれます。画面右側に取得できた座標が表示されます。


「再範囲選択」ボタンをクリックして、座標の取得をやり直すこともできます。


1列目が済んだら、同様にして2列目の座標を取得します。この作業を「マークシートの列数」分だけ繰り返します。

すべての列の座標を取得できたら、「保存」ボタンをクリックして取得した座標を保存します。


「保存」処理が完了すると、次のメッセージが表示されます。

参考:テンプレートの名前について
例 N_R25C03S08
N:ノーマル(通常の大きさ:解像度150~200dpi)
R:Row(行数)は25行
C:Col(列数)は3列
S:Selection(選択)は8個


「二値化テストの実行」ボタンをクリックすると、第1列めを「平滑化(ぼかし)処理&白黒反転して二値化」した画像の状態が確認できます。「マークあり」の部分が白く表示されていればOKです!
(プログラムは、この白部分の面積を計算して、マークの有無を判定しています)

「終了」ボタンをクリックして画面を閉じ、マーク(解答)欄座標の取得作業を終了します。

二値化テストを実行した場合は、終了ボタンをクリックする前に、保存ボタンをクリックすることを忘れないでください!

二値化の閾値と平滑化(ぼかし処理)のパラメータは、まずデフォルト設定でお試しください。

5.マークの読み取りを実行

これでマークを読む準備ができました。メニューの「テンプレート」をクリックし、表示されるサブメニューの「テンプレートの選択」をクリックします。


次のように、テンプレートを選択するWindowが表示されます。マークシートの形式に合ったテンプレートをクリックして選択し、決定をクリックします。

シングル/ダブルとあるのは、数学や教科「情報」のテストで、マークシート2枚1セットの採点を行うための設定です。選択肢数が16のマークシートを選ぶと、この設定も選択できるようになります(選択肢数が16未満のマークシートでは、この設定は利用できません)。

数学及び教科「情報」用の設定は、後日別記事として掲載する予定です。


次のメッセージが表示されます。「はい」をクリックしてください。


マークの読み取りを実行したいマークシート画像のあるフォルダを選択し、「Ok」ボタンをクリックしてください。


保存してあるマーカー(特徴点)画像をもとに、自動的にテンプレートマッチングが行われ、見つかったマーカー(特徴点)画像から、マークシートのマーク(解答)欄第1列第1行目の座標が計算され、それぞれが赤い矩形で囲まれて表示されることを確認してください。

Python環境を利用する場合(ここでワンクッション置くような感じで)テンプレートマッチングにしばらく時間がかかることがあります。同じプログラムを走らせているのですが、PCにより、このフリーズしたような時間の長さが極端に違うようです・・・、その辺の理由が私にはさっぱりわかりませんが・・・。

Python環境利用時に、この画面が表示されるまで、フリーズしたようになることがあります!


ここまでの設定操作が順調に進行していれば(抜け・落ち・欠けがなければ)、間違いなくテンプレートマッチングが成功し、マーカーと1列1行目が赤い矩形で囲まれるはずです。次のメッセージが表示されますので、お読みになったら「OK」ボタンをクリックしてください。


「読む」ボタンをクリックすると、マークシートの読み取りがスタートします。


画面下部の StringGrid に読み取り結果がリアルタイムで表示されます。また、読み取り完了後、処理にかかった時間が画面左下に表示されます。


8選択肢・25行・3列だから、合計600マーク ×3枚=1800マークの読み取りで、早ければ2013ミリ秒、遅くて2467ミリ秒で読んでます(PCの性能により、この値は変わります)。


遅かった方で1マークあたりの読み取り時間を計算すると、

2.467秒 ÷3≒ 0.82秒/枚
0.82 ÷ 600 ≒ 1.4ミリ秒/1マーク

そう書くと、すごく早いような気がしますが・・・

600マーク3枚で2.5秒だから、30枚ならその10倍で25秒かかります。平均的な高校の1学年分の生徒数を1学年8クラス320名とすると、さらに10倍で280秒程度、約5分処理時間が必要です。

300名分、5分だと慣れてくるとちょっと遅く感じてしまうかな? みたいな気が・・・

このプログラムには、内部的にPython環境を組み込んで高速動作させるモードがあります。数学用途の16選択肢・25行・3列で1200マーク/枚のマークシートで処理速度を計算・比較してみます。
(組み込みPythonの利用方法は後日ご案内します)

まず、Python環境を利用しない場合、1200マーク×40枚=1クラス分の48000マークを読むのにかかった時間が・・・


約78秒です。2枚1セットのダブルモードならその倍になります。
1枚(1200マーク)読むのに1.95秒かかってます。

次に、Python環境を利用した場合です。同じ読み取り条件で実験すると・・・


約11.5秒。8クラスあっても2分かかりません。ダブルモードでも4分未満。
1枚0.3秒未満で読み取ってます。

何やってもダメな自分にしては、よく頑張ったって正直、思います・・・。
よほど、びみょーなマークでない限り、期待した通り、ほぼ正しく読み取ってるし・・・。
かあさん、オレ、がんばったよ☆☆☆

まぁ このプログラム作成そのものに50万枚くらい採点できる時間をかけてますから・・・

それと合算すれば、
たぶん、プラマイ0ですー!!

6.読み取り結果のチェック

マークシートリーダーで最も重要な部分は、マーク読み取りの正確さであることは言うまでもありませんが、読み取り結果のチェック機能も非常に重要であると考えます。

人によってマークの濃さや大きさは少しずつ異なり、また、マークを訂正した箇所に残る消し跡も判定に少なからぬ影響を及ぼします。常に100%正しい読み取り結果が保証されないのが現実ですから、如何に効率よく、読み取り結果をチェックできるかで、プログラムの使用感はずいぶん変わってくると思います(CPUパワーにかなり依存したプログラムを書いておいて、そう言うのもナンですが・・・)。

自分自身の書いたものがベストだなんて、到底、思えませんが、このプログラムを書くにあたり、マークの読み取り部分と同等か、それ以上に頑張って書いたのが、この読み取り結果のチェック部分です。

機械との協働。機械との融和。これをテーマに、ヒトと機械とが一体化しての「快適なチェック作業」の実現を目指しました。

・・・が、プログラミング技術の未熟。自分自身の勉強不足。見い出した妥協点。等々の理由により、視覚による機械と協働してのチェックも、聴覚(音声出力)による機械と協働してのチェックも、いずれも全面的にマシンのCPUパワーに依存した、もっさりした感のある処理となってしまいました・・・。

処理性能の高いマシンなら、それなりに快適に作業できると思うのですが。以下、チェック機能の使い方です。

マーク読み取り結果のチェックを実行。


上の図の左のGUIから説明します。

白紙にチェックすると、マークがひとつもないシートのチェックは行わない(飛ばす)設定で動作します。この機能はデフォルトでON(チェックあり)です。

マーク(解答)がなかった場合の読み取り結果の表示が「999」です(デフォルトOFFです。このプログラムでは、「空欄」のフラグを「999」としています。マークの番号にも、得点にも「999」は通常ないことがその理由です。ちなみに複数マークは「99」と表示しています。色は「999」が「青」、「99」が「赤」です。少しでも視覚に訴えた方がチェックしやすいと考えました)。

ごく薄い色でマークされた答案が混じっていないことが大前提ですが、答案全体(1クラス分!)のマークの濃さが十分「濃い」と保証されていれば、チェック開始時のみ「999」のチェックを外してチェック(機械がきちんと空欄を識別していることをヒトが目視して確認)、で、確実に空欄を見分けていることが確認できたら、「999」にチェックして続行。こうすれば大変スムーズな確認作業を実現することができます。あくまでもごく薄くマークされたシートがないことが大前提ですが・・・

いずれにしても「Check!」ボタンをクリックすると、プログラムは次の「空欄(999)」もしくは「複数マーク(99)」を探し、それが見つかった場合は該当箇所を赤い矩形で囲んで表示します。処理性能の高い(CPUパワーのある)マシンであれば、それなりに快適に動作しますが、そうでない場合は、かなり「もっさり」した動作になりますので、イライラするかも知れません。ごめんなさい。

【空欄と判定した場合】

マークがない場合の表示例(設問番号25が空欄であった場合)

【複数マークありと判定した場合】

複数マークと判定した場合の表示例(設問番号43が複数マークであると判定)


複数マークの判定はパラメータ設定を厳し目にしてあります(上の図はそれがわかるよう、大きめに表示しました)。ごく小さなシミは「平滑化(ぼかし)」処理である程度消えますが、ある程度の面積があるシミや汚れは上のように複数マークと判定されます。

いずれの場合も、ヒトの眼で確認して、訂正の必要がなければ「Check!」ボタンをクリックしてチェックを続行。読み取り結果の訂正が必要な場合は、正しい値を直接入力します(上の場合であれば「2」と入力してください)。


【処理をスキップして次のシートへ】

「Skip」ボタンをクリックすると、現在チェックしているシートの残りの部分のチェックを省略し、次のシートのチェックへ移動します。チェック対象シートの残りの行が全部空欄であった場合などに利用してください。


【チェックの再実行】

「ReDo」をチェックすると、初めからチェックを再実行できます。

ReDoにチェックすると表示されるメッセージ①
ReDoにチェックすると表示されるメッセージ②


【音声読み上げ】

読み取り結果が表示されているStringGridの任意の行をクリックして、「▶」ボタンを押すとWindowsに標準搭載されている日本語の音声合成エンジン(Microsoft Haruka Desktop)の音声で読み取り結果をアナウンスしてくれます。

マークの読み取りが正しく行われているか・どうか、少しでもラクに確認できないかと考え、この機能を搭載しました。処理性能の高いマシンでないと快適な動作は期待できませんが、CPUパワーのあるマシンであればそれなりに使えると思います。

「▶」ボタンの下にある「×」ボタンをクリックすると、音声読み上げを途中で中止することができます。


【列を指定して、任意の行からその列の最後の行までのチェックをスキップ】

数学用のマークシート等で、第1問の解答をシート第1列にマーク、第2問の解答をシート第2列にマーク、第3問の解答を・・・というような設定にしたい場合、「指定列の任意の行から最後の行までをチェックの対象から外す」ことができます。以下、その方法です。

任意の行を指定して、その行以降のチェックをスキップできます。


図のいちばん左にある「Skip」にチェックすると、この機能が有効になり、続けて「Check!」ボタンをクリックすると、ここでの設定に基づいたチェックを実行できます。

上の例であれば、1列目25設問あるうちの20設問目以降25設問目までのチェックをスキップ(チェックは19設問まで実行)、2列目は設問番号26から始まるので34設問目以降50設問目までを、3列目は設問番号51から始まるので70設問目以降75設問目までのチェックをそれぞれスキップします。スキップの設定はComboBoxへ入力した指定値「以降」であることにご注意ください。

また、シートの型式により、列の指定の可否をプログラムが自動的に判断し、ComboBoxのEnabled プロパティが設定されます(上の例では4列目は指定不可)。

「覚」ボタンをクリックすると、現在の設定を ini ファイルに書き込んで記憶します。「消」ボタンをクリックすると「設定なし」の状態に初期化できます。

数学用途等で2枚1セットの処理を実行する場合は、1枚目と2枚目を分けてスキップ処理の設定を行うことができます(数学用途の処理方法は後日掲載します)。

7.CSVファイルへの書き出し

マークの有無の読み取り結果は、CSVファイルとExcel Book への書き出しが可能です。

【CSVファイルへの書き出し】


「ファイルへの出力」にある「CSV」をクリックして選択し、「書き出し」ボタンをクリックしてください。


上記の場所にCSV形式で、読み取り結果が出力されます。

フィールド名として1行目に「設問番号」、レコード名としてA列に「マークシート番号」が書き込まれます。

8.Excel Book の準備作業

【Excel Bookへの書き出し準備】

Excel Book への読み取り結果の書き出しは、自分用に(あれば便利かなー☆)と思って作成したものです。ですので、式の入ったセルを保護する等、第三者が使うことへの配慮は何一つ行っていません。セルに入力された式やVBAの内容をご自身でメンテナンスできる方なら、お使いいだけるかな? という程度のシロモノです。

添付した Excel Book はこれまでに何度も「実際に使用して動作に誤りがないことを確認済み」ですが、誤って式を削除したりした場合は(当然ですが)意図した通りに動作しません。ですので、こちらも動作保証は一切ありません。ご使用はあくまでも自己責任でお願いします。この Excel Book に対しても、このプログラムの使用要件にあります免責事項がそのまま適用されますことを申し添えます。

以下、試験実施前に行っておくとよい採点準備作業です。

eFile フォルダに「一般用マークと手書き併用採点シート.xltm」というマクロ有効テンプレートがあります。これをダブルクリックすると「一般用マークと手書き併用採点シート1.xlsx」という名前で新しい Excel Book が作られます。拡張子に注意してください。「.xlsx」です。このままでは期待通りに動作しませんので、適切な名前を付け、拡張子を「.xlsm」(マクロが有効な Excel Book )に変更して eFile フォルダ(必ずこのフォルダに保存してください!)に保存します。

ここでは test.xlsm という名前で保存したことにして説明を続けます。

「コンテンツの有効化」をクリックしてマクロが実行できるようにしてください。


【インターネットからダウンロードしたマクロ有効 Excel Book の取り扱い】

いつからこうなったのか、わかりませんが、インターネットからダウンロードした拡張子 xlsm の Excel Book をダブルクリックして開くと、次のメッセージが表示されるようになりました。

「編集を有効にする」をクリックすると・・・
マクロを動かすことができません!


こうなった時は、いったん Book を閉じて、その Excel ファイルを右クリックして表示されるサブメニューのプロパティをクリックして、全般タブのいちばん下にある「セキュリティ:」の「許可する」にチェックします(チェックする=マクロの実行をご自身の責任で行うことになります。どうか、ご注意ください)。

全般タブの下の方にあるセキュリティの設定。
マクロの実行をご自身の責任で行う場合は、「許可する」にチェックしてください。


「許可する」にチェックした状態で、「適用」をクリックすると「セキュリティ」の表示そのものが消えます。「あなたの責任でマクロの実行が可能になりました」ということなのでしょう。「OK」をクリックしてプロパティの設定画面を閉じます。


これでマクロが実行できるようになります。


【欠席者がいた場合】

Excel Book を利用して採点する場合、大変重要な注意事項があります。それは欠席者がいた場合の処理です。該当試験に欠席者がいる場合は、その欠席者の出席番号位置に未使用のマークシートを挿入し、シートが確実に出席番号順に並んでいることを確認してから、スキャナーでスキャンしてください。
※ 可能であれば、この用途専用に未使用のマークシートを複数枚、最初から手元に準備しておくとよいと思います。

重要 未使用のマークシートを欠席者の出席番号位置に挿入しておく!

これを忘れると、あとから「すーぱーめんどくさい」コトになります(もし、忘れたらマークシートのスキャンからもう一度、採点をやり直した方が効率がいいかもしれません)。


【受験者の氏名データを準備する】

test.xlsm をダブルクリックして開き、「コンテンツの有効化」を行ったら、いちばん最初に「名票への貼付元名票」シートをクリックして開き、ここに「採点対象者全員分の氏名」を準備してください。

もっとわかりやすく言うと、採点したいテストを受験した生徒全員の「クラス・出席番号・氏名・ふりがな・性別」データを「クラスごと」に「出席番号順」で、「名票への貼付元名票」シートに用意します。なんで「ふりがな」まで必要なのか? 疑問に思う方もいらっしゃるかもしれませんが、最近の若い方々のお名前は難読である場合が多く、採点結果を個票でお知らせする際に、個票の氏名欄のところに「ふりがな」も印刷しておくとスムーズに答案返却が行えます。そのための「ふりがな」準備です。

また、テストの受験者全員分の氏名データを1シートに準備する理由は、次のような使い方を想定しているからです。

(1)同じテストを受験 ⇨ クラス毎に採点用 Excel Book を用意するのは非効率的。
(2)採点用 Excel Book は1個だけ作成し、これをコピーして全クラス分を作る。

具体的には、eFile フォルダの Excel Book(test.xlsm)をコピーして、クラス別(AHR.xlsm)に名前を変えて MS_Reader.exe がある場所に保存。採点結果もコピーした Excel Book(AHR.xlsm) に書き込みます。さらに、この作業はすべてプログラムから自動実行します。

採点者は、採点結果が書き込まれた Excel Book(AHR.xlsm)を開いて、「名票への貼付元名票」シートに用意した氏名データから「A組の受験者の氏名データ(クラス・出席番号・氏名・ふりがな・性別)を範囲選択してコピーし、「名票」シートに値のみ貼り付けます。

こうすることで同じ内容のファイルを複数個準備することなく、言わば「採点原本」として利用する Excel Book を1つ作成するだけで、試験を実施した全クラス分の採点が可能となります。

ここでは「クラス」と表現しましたが、用意する氏名データを適宜変更すれば「講座」等の採点もまったく同じように行えます。※ プログラムの仕様としては、1回の採点作業で採点する人数を100名以下と想定していますが、実際の採点作業は1採点40名程度で行っています。ですので、40名程度を1つのまとまりとして採点していただく方向でお考えください。


【正解を入力】

氏名データの準備が完了したら、「正解」シートをクリックして表示し、設問毎に「正解」の選択肢の番号を入力します。設問がない場合(無解答でよい設問番号の欄)は空欄のままにしておきます。入力したら、入力内容に間違いがないか、よく確認し、上書き保存してください。

正解の入力を間違えるとたいへんなコトになります!
慎重に入力し、最低2回は間違いがないことを確認してください。


【配点を入力】

次に、「マークシート配点」シートをクリックして「配点」を入力します。入力と同時に合計が自動的に計算されます。入力が完了したら上書き保存してください。なお、この配点表の下には観点別評価の表もありますが、この表には一切入力しないでください(観点別評価の表は入力禁止です)。

配点を入力すると「合計」が自動計算されます。
確認作業にお役立てください。


【観点別評価の区分を入力】

次に、「マーク&手書き観点別評価」シートをクリックして「観点別評価の区分」を入力します。
「知識・技能 ⇨ 1」、「思考・判断・表現 ⇨ 2」として設問毎に、半角数字で入力してください。デフォルト設定では、すべての設問に「1」が入っています。解答を要しない設問は「空欄」にしてください。入力したら上書き保存します。


以上で、試験実施前の準備は終了です!

9.Excel Book への書き出し

重要 すべての Excel Book を閉じてから実行してください!

危険 Excelが起動した状態で実行すると重大なエラーが発生します!

Excel へデータを書き込む際は、上記注意事項を必ずお守りください。この注意を忘れて Excel が起動したまま、Excel Book への書き込みを実行すると最悪の場合、Excel のプロセスが幽霊のように残り、これを終了することが出来なくなって、復旧するには、システムの再起動しかない状態になります。未保存の重要なデータがあるような場合、当然そのデータは失われます。Excel Book へのデータ書き込み時は、Excel が起動していないことを(タスクバーに眠っている Excel Book がないことも含めて)十分確認した上で、書き込み作業を行ってください。


【書き出し処理】

マークシートを読み取り後、読み取り結果のチェックまで完了したら、Excel Book への読み取り結果の書き出しが可能となります。次のようにマークシートリーダーを操作してください。

最初に、ファイルへ出力の Excel のオプションボタンをクリックして選択します。すると、その右側にある「選択」ボタンがクリックできるようになりますから、このボタンをクリックしてください。


ファイル選択のダイアログが表示されますので、読み取り結果を書き込む Excel Book をクリックして選択し、その後、下にある「開く」ボタンをクリックします。Pathの指定は、デフォルトで eFile フォルダになっています。準備作業で作成した test.xlsm を eFile フォルダに保存したのは、この読み取り結果を書き込む Excel Book を選択する作業を円滑に実行するためです。


次のメッセージが表示されます。

重要 ここで Excel が起動していないことを必ず確認してください!

選択した Excel Book が書き込み先として表示されていることを確認し、「書き出し」ボタンをクリックします。


書き込みには、しばらく時間がかかります。次のメッセージが表示されるまでお待ちください。


すぐに書き込み結果を確認する場合は、「はい」をクリックします(ここでは「はい」をクリックしたものとして説明を続けます)。

「はい」をクリックした場合は、エクスプローラーが自動的に開きます。先ほど選択した「test.xlsm」のコピーが「Scanner_A.xlsm」として、eFile フォルダではなく、MS_Reader.exe のあるフォルダに生成されています。


ファイル名がなぜ「Scanner_A.xlsm」になったかというと、マークシートの読み取り元フォルダとして選択したのが、ProcData\Scanner_A であったためです。プログラムは、マークシートの読み取り元フォルダの名称をそのまま、原本「test.xlsm」をコピーして生成する読み取り結果書き込み先 Excel Book の名称として利用します。

マークシートの読み取り元フォルダの名称が、Excel Book の名称になります!


マークシートの読み取り元フォルダの名称が「R05_情報Ⅰ_1A」であれば、MS_Reader.exe のあるフォルダに「R05_情報Ⅰ_1A.xlsm」が生成されます。

ここは、この仕様に慣れるまで混乱が生じやすいところと思われます。しかし、この仕様(仕組み)を十分に理解して、マークシートリーダーを使いこなしている職場の同僚からは「よく考えられた採点システムだと思います」と言ってもらえました。うれしかったなー!!


【成績一覧表の印刷】

生成された Excel Book をダブルクリックして起動します。起動したら「名票への貼付元名票」タブをクリックして開き、採点対象クラス(等)の氏名データを範囲選択してコピーし、「名票」タブをクリックして B3 セルに値のみ貼り付けます。次に「採点」タブをクリックしてください。次のような画面が表示されます。「氏名がある場合のみチェックする」ボタンをクリックしてください。画面上方に表示されている平均点が正しく再計算されます。なお、欠席者の得点は「0」と表示されていますので、この場合は手動で「受験確認」のチェックを外し、平均点の計算対象から除外してください。

「氏名がある場合のみチェックする」をクリックしてください。


このシートは通常の印刷操作で印刷できます。ただし、デフォルト設定で100名分を2枚に分けて印刷する仕様となっているため、成績一覧表が1枚でよい場合は、次のように指定して1ページ分のみ印刷を実行してください。

成績一覧表を1枚だけ印刷したい場合の設定


【観点別評価を行う場合】

観点別評価を行う場合は、「正答率」タブをクリックして、上と同様の操作を行ってください。欠席者がいた場合の処理も同じです(このシートは印刷しません)。


【個票の印刷】

最後に、試験の採点結果を受験者に知らせる成績個票を印刷します。よー書いた。さすがに私も疲れました。あと、もぉちょっとです!

「個人表」タブをクリックします。次のような画面が表示されます(表示倍率は異なります)。まず、考査名と科目名を入力してください(忘れやすい部分です! ご注意願います)。印刷はVBAでマクロを組んであります。設問数に合った「印刷(QXX)」ボタンをクリックしてください。

重要 セルを保護していません。誤って式を消さないでください!


次の印刷フォームが表示されます。開始番号と終了番号を入力し、「印刷実行」をクリックします。

重要 印刷は途中で中止できません!

VBAではプログラム書いてない!のに、Engterキー押し下げでフォーカスが移動します・・・

この印刷は Excel の仕様上、印刷データをためてからイッキにプリンタへ送信という方法が取れません。1枚ずつ送信しますので、ちょっとギクシャクした感じで印刷が実行されます。プリンタが壊れているわけではありません。


【個票を個別に確認したい場合は?】

受験者個々の個票を確認したい場合は、A2 セルに「採点」シートの通番を入力します。いろいろなクラスの生徒が混在した講座の処理に対応するため、入力値は「出席番号とは異なる」ことにご注意願います。

採点シートの通番を入力します!


個票を確認したい受験者の通番は「採点」シートを表示して確認してください。

受験者の通番を確認します。


【壊しちゃったときは?】

個人表シートを壊してしまった時は、次のようにすれば直せます。「個人票_Back」タブをクリックします(このシートは絶対に非表示にしないでください)。A 列の左、1行めの上(図の〇印を付けた部分)を右クリックしてシート全体を選択し、表示されるサブメニューのコピーをクリックします。

A 列の左・1行めの上を右クリック!
シート全部をコピーします。


個人表シートに戻って、先ほどと同じ A 列の左・1行目の上を右クリックして表示されるサブメニューの「数式fx」をクリックします(罫線データ等を壊してしまった場合は、すべてを貼り付けます)。

数式が壊れた場合は数式を貼り付けます。
面倒な場合は、いちばん左の全部「貼り付け」でもOK!

10.マークシート印刷用紙について

紙の「白さ」の度合いを「白色度」というそうです。このマークシートリーダーで読み取りに使用したマークシートはすべて「再生紙 or 再生コピー用紙」と呼ばれる紙に印刷したものです。

ですから、ここで紹介したマークシートの読み取り結果は、すべて「白色度70%」前後の「再生紙」に印刷してのもので、ホームセンターで一般的に販売されているような「白色度」が「再生紙」よりはるかに高い「真っ白に見える」用紙を用いての読み取り結果ではないことに、十分ご注意願います。

マークシートの印刷に使用する紙の「白色度」によっては、読み取りパラメータ設定の見直しが必要になるかもしれません(私自身は、実験・試行していませんので正確なことはわかりませんが)。入手可能なすべての紙について、実験することは現実的に無理でありますので、マークシートを印刷する用紙については、本ソフトウェア使用者の責任で十分な試行を行い、確実に動作するパラメータ設定を行った上で、このプログラムをお使いいただけますよう、お願いいたします。

印刷はインクジェットプリンタで行うことを推奨しましたが、長期にわたって使用していない(メンテナンスもしていない)インクジェットプリンタ(複合機)では、インクの吸い込みに問題が生じ、「いくら調整しても・何度クリーニングを行っても」期待した濃度での印刷ができないということも経験しました。サービスマンの方に伺ったところ、「こういう状態になると通常のクリーニングではなかなか復旧しない」と教えていただき、あらためて日常的に使用してインクを動かすことと、不具合が見えたらすぐにメンテナンスをお願いすることの大切さに気づいたこともあります。

そのサービスマンの方からは、マークシートに付着していた消しゴムの「屑」がスキャナーのローラー等可動部の動きを悪くして、マークシートがやや斜めにスキャンされたりする原因となり得ることも教えていただきました。実際に大量のマークシートを読み取ってきた複合機のスキャナー部分からは、かなりの量の消しゴム屑が・・・。受験者には消しゴム屑をよーく落としてから答案(マークシート)を提出するよう注意しておく必要があります。まさに塵も積もればなんとやら・・・です。

また、ご使用のスキャナーの読み取り設定によっては(デフォルトの読み取り設定が)0~255段階のグレースケールでなく、カラーであったり、ある閾値で白黒二値化しての読み取りであったりという、私の想定外の設定であることも、当然のようにあり得ると思います。それがカラー画像であった場合の影響はほとんどないと思われますが、ある閾値での白黒二値化画像であった場合は、判定に重大な影響を及ぼす可能性があります。ですので、マークシートの読み取りに、使用されるスキャナーの読み取り設定に関して、予め、使用者様の責任で十分ご確認いただけますよう、併せてお願い申し上げます。

11.まとめ

このマークシートリーダーで出来ること、出来ないことをまとめました。

【出来ること】

・マークシートのJpeg画像を回転&適切なサイズに縮小
・マークシート画像のマーク読み取り(1設問当たり最大16選択肢まで対応)
・読み取り結果の確認(GUI & 音声出力)
・読み取り結果のCSVファイル出力
・読み取り結果を採点結果通知用Excel Bookへ出力(新教育課程に対応)
・共通テスト形式の数学試験に対応(選択肢:-、±、0-9、記号:a~d)※ 後日掲載します。
・共通テスト形式の情報Ⅰ試験に対応(選択肢:0始まりの設定も可能)※ 後日掲載します。
・使用環境に合わせて各種パラメータ設定を変更可能
 ⇨ ScanSnap iX1500のノーマルモード(解像度150dpi相当?)、もしくはEPSON PX-M7110F(解像度200dpi)でスキャンしたJpeg画像のマーク読み取りに最適化した値をデフォルト値に設定済み。

【出来ないこと】

・1設問について、複数の解答が設定された採点
・前問の解答内容に応じて、次の問いの解答が変わる採点
・その他、答案1枚のみの採点等、このプログラムで想定外の採点全て
・1回の読み取り操作で処理できるJpeg画像は99枚までで、100枚を超える枚数は処理できません。

【その他の使用方法】

MS_Reader.exe の「ヘルプ」にある「PDFを表示」をクリックすると利用方法の手引きがお使いのPDFリーダーで表示されます。マークシートの作り方等、このブログの記事にないことも書いてありますので、必要に応じてこちらも併せてご参照いただけますよう、お願いいたします。

12.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。ここに記載した内容及びダウンロードしたプログラムを利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。