Behavioral techniques for controlling visual stimuli to modulate visual processing in the brain and their implementation in augmented reality technology
Paper
Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Java · 537 lines · 24 KB · no license
- package com.example.opencv_test10;
- import androidx.annotation.NonNull;
- //import androidx.appcompat.app.AppCompatActivity;
- //import android.app.ActionBar;
- import android.media.AudioManager;
- import android.media.ToneGenerator;
- import android.os.Bundle;
- import android.os.Environment;
- import android.util.Log;
- //import android.view.ActionMode;
- import android.view.GestureDetector;
- import android.view.MotionEvent;
- import android.view.ScaleGestureDetector;
- //import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
- import android.view.SurfaceView;
- import android.view.View;
- import android.view.Window;
- //import android.view.WindowManager;
- import org.opencv.android.BaseLoaderCallback;
- import org.opencv.android.CameraActivity;
- import org.opencv.android.CameraBridgeViewBase;
- import org.opencv.android.LoaderCallbackInterface;
- import org.opencv.android.OpenCVLoader;
- import org.opencv.core.Core;
- import org.opencv.core.CvType;
- import org.opencv.core.Mat;
- import org.opencv.core.Rect;
- import org.opencv.core.Scalar;
- import org.opencv.core.Size;
- //import org.opencv.core.Scalar;
- import org.opencv.imgcodecs.Imgcodecs;
- import org.opencv.imgproc.Imgproc;
- import java.io.File;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Date;
- import java.util.List;
- import static java.lang.Math.abs;
- import static org.opencv.android.CameraRenderer.LOGTAG;
- import static org.opencv.core.Core.BORDER_DEFAULT;
- import static org.opencv.imgproc.Imgproc.THRESH_TOZERO;
- public class MainActivity extends CameraActivity {
- Mat img_zero, img_filtered, img_stereo;
- Mat img_rgba, img_gray, img_invgray, img_isolumR, img_isolumG;
- Mat img_sobel01, img_sobel10, img_temp8UC;
- Mat img_noise, img_gray32F;
- boolean used_rgba, used_invgray, used_isolumRG; // used_gray, used_sobels
- ArrayList<Mat> channels_rgba;
- Mat mat_lut_Red, mat_lut_Green;
- Rect half_rect, srcL_rect, srcR_rect, dstL_rect, dstR_rect;
- int cam_width,cam_height, cam_half_width, cam_quarter_width;
- int capture = 0;
- int imgtype = 1;
- int separation = 100;
- private static String LOGTAG = "OpenCV_Log";
- private CameraBridgeViewBase mOpenCvCameraView;
- private GestureDetector gestureDetector;
- private ScaleGestureDetector scaleGestureDetector;
- private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
- @Override
- public void onManagerConnected(int status) {
- switch (status){
- case LoaderCallbackInterface.SUCCESS:{
- Log.v(LOGTAG,"OpenCV Loaded");
- mOpenCvCameraView.enableView();
- } break;
- default:
- {
- super.onManagerConnected(status);
- } break;
- }
- super.onManagerConnected(status);
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- final android.view.WindowInsetsController insetsController = getWindow().getInsetsController();
- if (insetsController != null) {
- insetsController.hide(android.view.WindowInsets.Type.statusBars());
- insetsController.setSystemBarsBehavior(android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
- }
- mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.opencv_surface_view);
- mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
- mOpenCvCameraView.setCvCameraViewListener(cvCameraViewListener);
- gestureDetector = new GestureDetector(this, new GestureListener());
- scaleGestureDetector = new ScaleGestureDetector(this, new PinchZoomListener());
- mOpenCvCameraView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- gestureDetector.onTouchEvent(event);
- scaleGestureDetector.onTouchEvent(event);
- return true;
- }
- });
- }
- private class GestureListener extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- capture = 1;
- return true;
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- int pretype = imgtype;
- float swipeX = e1.getX() - e2.getX();
- float swipeY = e1.getY() - e2.getY();
- if (swipeY > 50 && abs(swipeY) > abs(swipeX)) { // Upward
- imgtype++;
- if(imgtype > 12) imgtype = 0;
- }
- else if (swipeY < -50 && abs(swipeY) > abs(swipeX)) { // Downward
- imgtype--;
- if(imgtype < 0) imgtype = 12;
- }
- if(imgtype==pretype)
- return false;
- boolean pre_used_rgba=used_rgba, pre_used_invgray=used_invgray; //pre_used_gray=used_gray,
- boolean pre_used_isolumRG=used_isolumRG; //pre_used_sobels=used_sobels
- used_rgba=false; used_invgray=false; used_isolumRG=false; //used_gray=false; used_sobels=false;
- switch(imgtype) {
- case 0: // RGB
- used_rgba = true;
- break;
- case 1: // Gray
- //used_gray = true;
- break;
- case 2: // Red Only
- //used_gray = true;
- used_isolumRG = true;
- break;
- case 3: // Red-inv Only
- //used_gray = true;
- used_invgray = true; used_isolumRG = true;
- break;
- case 4: // Green Only
- //used_gray = true;
- used_invgray = true; used_isolumRG = true;
- break;
- case 5: // Green-inv Only
- //used_gray = true;
- used_isolumRG = true;
- break;
- case 6: // Red-Green
- //used_gray = true;
- used_isolumRG = true;
- break;
- case 7: // Green-Red
- //used_gray = true;
- used_isolumRG = true; used_invgray = true;
- break;
- case 8: // Contour
- //used_gray = true; used_sobels = true;
- break;
- case 11: // 2nd-order-inv
- used_invgray = true;
- break;
- case 12: // Gray-inv
- used_invgray = true;
- break;
- default: // 7~9, Default == Gray
- //used_gray = true;
- break;
- }
- if(pre_used_rgba==false && used_rgba==true) {
- img_rgba = new Mat(cam_height, cam_width, CvType.CV_8UC4);
- channels_rgba = new ArrayList<>(4);
- }
- //if(pre_used_gray==false && used_gray==true) img_gray = new Mat(cam_height, cam_width, CvType.CV_8U);
- if(pre_used_invgray==false && used_invgray==true) img_invgray = new Mat(cam_height, cam_width, CvType.CV_8U);
- if(pre_used_isolumRG==false && used_isolumRG==true) {
- img_isolumR = new Mat(cam_height, cam_width, CvType.CV_8U);
- img_isolumG = new Mat(cam_height, cam_width, CvType.CV_8U);
- }
- //if(pre_used_sobels==false && used_sobels==true) {
- // img_sobel01 = new Mat(cam_height, cam_width, CvType.CV_16S);
- // img_sobel10 = new Mat(cam_height, cam_width, CvType.CV_16S);
- // img_temp8UC = new Mat(cam_height, cam_width, CvType.CV_8U);
- //}
- if(pre_used_rgba==true && used_rgba==false) {
- img_rgba.release();
- channels_rgba.get(0).release();
- channels_rgba.get(1).release();
- channels_rgba.get(2).release();
- channels_rgba.get(3).release();
- }
- //if(pre_used_gray==true && used_gray==false) img_gray.release();
- if(pre_used_invgray==true && used_invgray==false)
- img_invgray.release();
- if(pre_used_isolumRG==true && used_isolumRG==false) {
- img_isolumR.release();
- img_isolumG.release();
- }
- //if(pre_used_sobels==true && used_sobels==false) {
- // img_sobel01.release();
- // img_sobel10.release();
- // img_temp8UC.release();
- //}
- return true;
- }
- }
- public class PinchZoomListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
- @Override
- public boolean onScale(@NonNull ScaleGestureDetector detector) {
- //float temp_scale = detector.getScaleFactor();
- float temp_span1 = detector.getCurrentSpan();
- float temp_span0 = detector.getPreviousSpan();
- float temp_val = temp_span1 - temp_span0;
- separation += temp_val;
- if(separation<0) separation=0;
- if(separation>cam_half_width) separation=cam_half_width;
- Log.d("ScaleGestureDetector", "Separation: " + separation);
- return true;
- }
- }
- @Override
- protected List<?extends CameraBridgeViewBase> getCameraViewList() {
- return Collections.singletonList(mOpenCvCameraView);
- }
- private CameraBridgeViewBase.CvCameraViewListener2 cvCameraViewListener = new CameraBridgeViewBase.CvCameraViewListener2() {
- private int lut_Red_int[] = {
- 27, 27, 44, 44, 56, 56, 66, 66, 74, 74, 81, 81, 88, 88, 94, 94,
- 100, 100, 100, 105, 105, 105, 110, 110, 110, 114, 114, 114, 119, 119, 119, 123,
- 123, 123, 127, 127, 127, 131, 131, 131, 134, 134, 134, 138, 138, 138, 141, 141,
- 141, 145, 145, 145, 148, 148, 148, 151, 151, 151, 154, 154, 154, 157, 157, 157,
- 159, 159, 159, 162, 162, 162, 165, 165, 165, 167, 167, 167, 170, 170, 170, 172,
- 172, 172, 175, 175, 175, 177, 177, 177, 179, 179, 179, 181, 181, 181, 183, 183,
- 183, 186, 186, 186, 188, 188, 188, 190, 190, 190, 192, 192, 192, 193, 193, 193,
- 195, 195, 195, 197, 197, 197, 199, 199, 199, 201, 201, 201, 202, 202, 202, 204,
- 204, 204, 206, 206, 206, 207, 207, 207, 209, 209, 209, 210, 210, 210, 212, 212,
- 212, 213, 213, 213, 215, 215, 215, 216, 216, 216, 217, 217, 217, 219, 219, 219,
- 220, 220, 220, 221, 221, 221, 222, 222, 222, 224, 224, 224, 225, 225, 225, 226,
- 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231,
- 231, 232, 232, 232, 233, 233, 233, 234, 234, 234, 235, 235, 235, 236, 236, 236,
- 237, 237, 237, 238, 238, 238, 239, 239, 239, 240, 240, 240, 241, 241, 241, 242,
- 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, 246, 246, 246, 247, 247,
- 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255 };
- private int lut_Green_int[] = {
- 143, 143, 142, 142, 141, 141, 140, 140, 139, 139, 138, 138, 137, 137, 136, 136,
- 135, 135, 135, 134, 134, 134, 133, 133, 133, 132, 132, 132, 131, 131, 131, 130,
- 130, 130, 129, 129, 129, 128, 128, 128, 127, 127, 127, 126, 126, 126, 125, 125,
- 125, 124, 124, 124, 123, 123, 123, 122, 122, 122, 121, 121, 121, 120, 120, 120,
- 119, 119, 119, 118, 118, 118, 117, 117, 117, 116, 116, 116, 115, 115, 115, 114,
- 114, 114, 113, 113, 113, 112, 112, 112, 111, 111, 111, 110, 110, 110, 109, 109,
- 109, 108, 108, 108, 107, 107, 107, 106, 106, 106, 105, 105, 105, 104, 104, 104,
- 103, 103, 103, 102, 102, 102, 101, 101, 101, 100, 100, 100, 99, 99, 99, 98,
- 98, 98, 97, 97, 97, 96, 96, 96, 95, 95, 95, 94, 94, 94, 93, 93,
- 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88, 88,
- 87, 87, 87, 86, 86, 86, 85, 85, 85, 84, 84, 84, 83, 83, 83, 82,
- 82, 82, 81, 81, 81, 80, 80, 80, 79, 79, 79, 78, 78, 78, 77, 77,
- 77, 76, 76, 76, 75, 75, 75, 74, 74, 74, 73, 73, 73, 72, 72, 72,
- 71, 71, 71, 70, 70, 70, 69, 69, 69, 68, 68, 68, 67, 67, 67, 65,
- 65, 65, 64, 64, 64, 63, 63, 63, 62, 62, 62, 60, 60, 60, 59, 59,
- 57, 57, 56, 56, 54, 54, 52, 52, 50, 50, 49, 49, 47, 47, 44, 44 };
- private byte[] lut_Red, lut_Green; // Unsigned (0-255) in OpenCV
- @Override
- public void onCameraViewStarted(int width, int height) {
- cam_width = width;
- cam_height = height;
- cam_half_width = width/2;
- cam_quarter_width = cam_half_width/2;
- half_rect = new Rect(0,0,cam_half_width, cam_height);
- srcL_rect = new Rect(0,0,cam_half_width, cam_height);
- srcR_rect = new Rect(separation,0,cam_half_width, cam_height);
- dstL_rect = new Rect(0,0, cam_half_width, cam_height);
- dstR_rect = new Rect(cam_half_width,0, cam_half_width, cam_height);
- img_stereo = new Mat(cam_height, cam_width, CvType.CV_8UC4);
- img_filtered = new Mat(cam_height, cam_width, CvType.CV_8UC4);
- img_zero = Mat.zeros(cam_height, cam_width, CvType.CV_8U);
- imgtype = 1;
- //used_gray = true;
- used_rgba = false; used_invgray = false; used_isolumRG = false; //used_sobels = false;
- img_gray = new Mat(cam_height, cam_width, CvType.CV_8U);
- // For controlling time
- img_sobel01 = new Mat(cam_height, cam_width, CvType.CV_16S);
- img_sobel10 = new Mat(cam_height, cam_width, CvType.CV_16S);
- img_temp8UC = new Mat(cam_height, cam_width, CvType.CV_8U);
- img_noise = new Mat(cam_height, cam_width, CvType.CV_32F);
- img_gray32F = new Mat(cam_height, cam_width, CvType.CV_32F);
- lut_Red = new byte[256];
- lut_Green = new byte[256];
- for (int i = 0; i < 256; i++) {
- lut_Red[i] = (byte) (lut_Red_int[i] & 0xFF);
- lut_Green[i] = (byte) (lut_Green_int[i] & 0xFF);
- }
- mat_lut_Red = new Mat(256, 1, CvType.CV_8UC1);
- mat_lut_Red.put(0, 0, lut_Red);
- mat_lut_Green = new Mat(256, 1, CvType.CV_8UC1);
- mat_lut_Green.put(0, 0, lut_Green);
- Log.d(LOGTAG,"(Width, Height)=("+Integer.toString(width)+", "+Integer.toString(height)+")");
- Log.d(LOGTAG,"(HWidth, QWidth)=("+Integer.toString(cam_half_width)+", "+Integer.toString(cam_quarter_width)+")");
- }
- @Override
- public void onCameraViewStopped() {
- img_zero.release();
- img_stereo.release();
- img_filtered.release();
- mat_lut_Red.release();
- mat_lut_Green.release();
- if(used_rgba==true) {
- img_rgba.release();
- channels_rgba.get(0).release();
- channels_rgba.get(1).release();
- channels_rgba.get(2).release();
- channels_rgba.get(3).release();
- }
- img_gray.release();
- img_sobel01.release();
- img_sobel10.release();
- img_temp8UC.release();
- img_noise.release();
- img_gray32F.release();
- if(used_invgray==true) img_invgray.release();
- if(used_isolumRG==true) {
- img_isolumR.release();
- img_isolumG.release();
- }
- }
- @Override
- public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
- img_gray = inputFrame.gray();
- if(used_rgba==true) {
- img_rgba = inputFrame.rgba();
- Core.split(img_rgba, channels_rgba);
- }
- if(used_invgray==true) Core.bitwise_not(img_gray,img_invgray);
- //Imgproc.Canny(img_gray, img_filtered, 50, 100*3);
- double adjust = 0.2;
- switch(imgtype) {
- case 0: // RGB
- Core.merge(new ArrayList<>(Arrays.asList(channels_rgba.get(0), channels_rgba.get(1), channels_rgba.get(2), img_zero)), img_filtered);
- break;
- case 1: // Gray
- Core.merge(new ArrayList<>(Arrays.asList(img_gray, img_gray, img_gray, img_zero)), img_filtered);
- break;
- case 2: // Red Only
- Core.LUT(img_gray, mat_lut_Red, img_isolumR);
- Core.merge(new ArrayList<>(Arrays.asList(img_isolumR, img_zero, img_zero, img_zero)), img_filtered);
- break;
- case 3: // Red-inv Only
- Core.LUT(img_invgray, mat_lut_Red, img_isolumR);
- Core.merge(new ArrayList<>(Arrays.asList(img_isolumR, img_zero, img_zero, img_zero)), img_filtered);
- break;
- case 4: // Green Only
- Core.LUT(img_invgray, mat_lut_Green, img_isolumG);
- Core.merge(new ArrayList<>(Arrays.asList(img_zero, img_isolumG, img_zero, img_zero)), img_filtered);
- break;
- case 5: // Green-inv Only
- Core.LUT(img_gray, mat_lut_Green, img_isolumG);
- Core.merge(new ArrayList<>(Arrays.asList(img_zero, img_isolumG, img_zero, img_zero)), img_filtered);
- break;
- case 6: // Red-Green
- Core.LUT(img_gray, mat_lut_Red, img_isolumR);
- Core.LUT(img_gray, mat_lut_Green, img_isolumG);
- Core.merge(new ArrayList<>(Arrays.asList(img_isolumR, img_isolumG, img_zero, img_zero)), img_filtered);
- break;
- case 7: // Green-Red
- Core.LUT(img_invgray, mat_lut_Red, img_isolumR);
- Core.LUT(img_invgray, mat_lut_Green, img_isolumG);
- Core.merge(new ArrayList<>(Arrays.asList(img_isolumR, img_isolumG, img_zero, img_zero)), img_filtered);
- break;
- case 8: // Contour
- Imgproc.GaussianBlur(img_gray, img_temp8UC, new Size(3,3), 0, 0, BORDER_DEFAULT);
- Imgproc.Sobel(img_temp8UC, img_sobel01, CvType.CV_16S, 0,1);
- Imgproc.Sobel(img_temp8UC, img_sobel10, CvType.CV_16S, 1,0);
- Core.convertScaleAbs(img_sobel01, img_sobel01);
- Core.convertScaleAbs(img_sobel10, img_sobel10);
- Core.addWeighted(img_sobel01, 1, img_sobel10, 1, 0, img_temp8UC); // Thresholded at 255
- //Imgproc.threshold(img_temp8UC,img_temp8UC,70,255,THRESH_TOZERO);
- Core.merge(new ArrayList<>(Arrays.asList(img_temp8UC, img_temp8UC, img_temp8UC, img_zero)), img_filtered);
- break;
- case 9: // 1st order
- Core.randu(img_noise,0, 0.5+adjust/2.0);
- img_gray.convertTo(img_gray32F, CvType.CV_32F);
- Core.normalize(img_gray32F, img_gray32F, 0, 1, Core.NORM_MINMAX, CvType.CV_32F);
- Core.multiply(img_gray32F, new Scalar(1.0 - (0.5+adjust/2.0)), img_gray32F);
- Core.add(img_gray32F, img_noise, img_gray32F);
- Core.pow(img_gray32F,1.0/2.218, img_gray32F);
- Core.multiply(img_gray32F, new Scalar(255), img_gray32F);
- img_gray32F.convertTo(img_temp8UC, CvType.CV_8UC1);
- Core.merge(new ArrayList<>(Arrays.asList(img_temp8UC, img_temp8UC, img_temp8UC, img_zero)), img_filtered);
- break;
- case 10: // 2nd-order (LowContrast -> HighContrast)
- Core.randu(img_noise,-0.5,+0.5);
- img_gray.convertTo(img_gray32F, CvType.CV_32F);
- Core.multiply(img_gray32F, new Scalar(1.0 - adjust), img_gray32F);
- Core.add(img_gray32F, new Scalar(255*adjust), img_gray32F);
- Core.multiply(img_gray32F, img_noise, img_gray32F);
- Core.normalize(img_gray32F, img_gray32F, 0, 1, Core.NORM_MINMAX, CvType.CV_32F);
- Core.pow(img_gray32F,1.0/2.218, img_gray32F);
- Core.multiply(img_gray32F, new Scalar(255), img_gray32F);
- img_gray32F.convertTo(img_temp8UC, CvType.CV_8UC1);
- Core.merge(new ArrayList<>(Arrays.asList(img_temp8UC, img_temp8UC, img_temp8UC, img_zero)), img_filtered);
- break;
- case 11: // 2nd-order-inv (LowContrast -> HighContrast)
- Core.randu(img_noise,-0.5,+0.5);
- img_invgray.convertTo(img_gray32F, CvType.CV_32F);
- Core.multiply(img_gray32F, new Scalar(1.0 - adjust), img_gray32F);
- Core.add(img_gray32F, new Scalar(255*adjust), img_gray32F);
- Core.multiply(img_gray32F, img_noise, img_gray32F);
- Core.normalize(img_gray32F, img_gray32F, 0, 1, Core.NORM_MINMAX, CvType.CV_32F);
- Core.pow(img_gray32F,1.0/2.218, img_gray32F);
- Core.multiply(img_gray32F, new Scalar(255), img_gray32F);
- img_gray32F.convertTo(img_temp8UC, CvType.CV_8UC1);
- Core.merge(new ArrayList<>(Arrays.asList(img_temp8UC, img_temp8UC, img_temp8UC, img_zero)), img_filtered);
- break;
- default: // 12: Default == Gray-inv
- Core.merge(new ArrayList<>(Arrays.asList(img_invgray, img_invgray, img_invgray, img_zero)), img_filtered);
- break;
- }
- srcL_rect = new Rect(cam_quarter_width-separation/2,0, cam_half_width, cam_height);
- srcR_rect = new Rect(cam_quarter_width+separation/2,0, cam_half_width, cam_height);
- img_filtered.submat(srcL_rect).copyTo(img_stereo.submat(dstL_rect));
- img_filtered.submat(srcR_rect).copyTo(img_stereo.submat(dstR_rect));
- if(capture==1) // Contour test!!
- {
- File savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); // "storage/emulated/0/Pictures" in Internal storage
- File saveDir = new File(savePath + "/OCV/"); // "storage/emulated/0/Pictures/OCV" in Internal storage
- Log.d(LOGTAG,"saveDir="+saveDir);
- if(!saveDir.exists()) saveDir.mkdirs();
- String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
- Mat imt_output = new Mat(cam_height, cam_width, CvType.CV_8UC4);
- if(used_rgba==false) {
- img_rgba = new Mat(cam_height, cam_width, CvType.CV_8UC4);
- img_rgba = inputFrame.rgba();
- Imgcodecs.imwrite(saveDir + "/" + timeStamp+"_rgba.png", img_rgba);
- img_rgba.release();
- } else
- Imgcodecs.imwrite(saveDir + "/" + timeStamp+"_rgba.png", img_rgba);
- Imgcodecs.imwrite(saveDir + "/" + timeStamp+"_gray.png", img_gray);
- capture = 0;
- ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
- toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
- imt_output.release();
- if(used_rgba==false) img_rgba.release();
- }
- return img_stereo;
- }
- };
- @Override
- public void onPause() {
- super.onPause();
- if(mOpenCvCameraView!=null) {
- mOpenCvCameraView.disableView();
- }
- }
- @Override
- public void onResume() {
- super.onResume();
- if(!OpenCVLoader.initDebug()) {
- Log.d(LOGTAG, "OpenCV not found, Initializing");
- OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION,this,mLoaderCallback);
- } else {
- mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
- }
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- if(mOpenCvCameraView!=null) {
- mOpenCvCameraView.disableView();
- }
- }
- }
ARNeurosci AndroidApp.java, no license · at the source
Overview
- Zaven P. and Sonia Akian College of Science and Engineering, American University of Armenia, Yerevan, Armenia
- Department of Psychology, Russian-Armenian (Slavonic) University, Yerevan, Armenia
- School of Psychology, HSE University, Moscow, Russia
- Faculty of Education Psychology and Sociology, Armenian State Pedagogical University, Yerevan, Armenia
- Centre for Cognition and Decision Making, Institute for Cognitive Neuroscience, HSE University, Moscow, Russia
Abstract
This study reviews the behavioral techniques that control visual stimuli to systematically modulate visual processing in an observer’s brain. These techniques are indirect but more affordable than more-direct techniques for stimulating the brain. The limitations of these techniques and the calibrations necessary for them are also discussed. Some of the behavioral techniques can be also used in field studies by making use of Augmented Reality (AR) technology and a head-mounted display (HMD). The AR HMDs for the behavioral techniques was assembled by combining a smartphone and a wearable stereoscope, both of which were also affordable, as a proof-of-concept. The reviewed behavioral techniques make it possible that researchers with limited budgets can conduct neuroscience studies and that students can learn about these subjects in low-income countries or in underfunded institutions. It can contribute to the democratization of neuroscience and the global equity of scientific research, as well as to broadening the populations studied in cognitive and neuroscience.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repository
Its files are read in the Code ↔ Paper reader above.
OSF hz7b9
Availability: 1 check, the latest on 7 October 2026: the link answers (HTTP 200)
- 7 October 2026: the link answers (HTTP 200)
1 file
- ARNeurosci AndroidApp.java, Java, 537 lines
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 1 script, each with its path and the digest of its content;
- no match between paragraphs and code yet;
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 7 October 2026: the first record
Recorded: type, language, journal, volume, pages, dates, 8 authors, 6 keywords, 186 references.
Cite
This paper
Sawada, T., Dvoeglazova, M., Zargaryan, A., Tamrazyan, A., Kozhevnikova, V. G., Berberyan, A., Feurra, M., & Gorbunova, E. S. (2026). Behavioral techniques for controlling visual stimuli to modulate visual processing in the brain and their implementation in augmented reality technology. Frontiers in neuroscience, 20, 1925212.
BibTeX
@article{sawada2026behav
author = {Sawada, Tadamasa and Dvoeglazova, Maria and Zargaryan, Alla and Tamrazyan, Anna and Kozhevnikova, Valeria G and Berberyan, Asya and Feurra, Matteo and Gorbunova, Elena S},
title = {{Behavioral techniques for controlling visual stimuli to modulate visual processing in the brain and their implementation in augmented reality technology}},
journal = {Frontiers in neuroscience},
year = {2026},
month = oct,
volume = {20},
pages = {1925212},
publisher = {Frontiers Media SA},
issn = {1662-4548},
pmcid = {PMC13640456}
}
RIS
TY - JOUR
AU - Sawada, Tadamasa
AU - Dvoeglazova, Maria
AU - Zargaryan, Alla
AU - Tamrazyan, Anna
AU - Kozhevnikova, Valeria G
AU - Berberyan, Asya
AU - Feurra, Matteo
AU - Gorbunova, Elena S
TI - Behavioral techniques for controlling visual stimuli to modulate visual processing in the brain and their implementation in augmented reality technology
T2 - Frontiers in neuroscience
J2 - Front Neurosci
PY - 2026
DA - 2026/
VL - 20
SP - 1925212
SN - 1662-4548
PB - Frontiers Media SA
LA - en
ER -
CSL-JSON
{
"id": "pmcid:PMC13640456",
"type": "article-journal",
"title": "Behavioral techniques for controlling visual stimuli to modulate visual processing in the brain and their implementation in augmented reality technology",
"container-title": "Frontiers in neuroscience",
"author": [
{
"family": "Sawada",
"given": "Tadamasa"
},
{
"family": "Dvoeglazova",
"given": "Maria"
},
{
"family": "Zargaryan",
"given": "Alla"
},
{
"family": "Tamrazyan",
"given": "Anna"
},
{
"family": "Kozhevnikova",
"given": "Valeria G"
},
{
"family": "Berberyan",
"given": "Asya"
},
{
"family": "Feurra",
"given": "Matteo"
},
{
"family": "Gorbunova",
"given": "Elena S"
}
],
"container-title-short":
"volume": "20",
"page": "1925212",
"PMCID": "PMC13640456",
"ISSN": "1662-4548",
"publisher": "Frontiers Media SA",
"language": "en",
"issued": {
"date-parts": [
[
2026,
10,
7
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.3758/s13414-024-02866-x
- Involvement of the superior colliculi in crossmodal correspondences.Journal: Attention, perception & psychophysicsIn common: 8 references
- [2] doi:10.1371/journal.pcbi.1011704 [code]
- Normalization by orientation-tuned surround in human V1-V3.Journal: PLoS computational biologyIn common: 6 references
- [3] doi:10.3389/fnins.2023.1200661 [code]
- A mechanistic account of visual discomfort.Journal: Frontiers in neuroscienceIn common: 6 references
- [4] doi:10.1038/s42003-025-08871-6 [code]
- Spatially global effects of feature-based attention in functional subdivisions of human subcortical nuclei.Journal: Communications biologyIn common: 5 references
- [5] doi:10.1038/s42003-023-04912-0 [code]
- Correlated variability in primate superior colliculus depends on functional class.Journal: Communications biologyIn common: 5 references
- [6] doi:10.3390/brainsci14080753
- Neural Substrates for Early Data Reduction in Fast Vision: A Psychophysical Investigation.Journal: Brain sciencesIn common: 5 references
- [7] doi:10.1038/s41598-025-07644-9
- Optimal feature encoding in early vision.Journal: Scientific reportsIn common: 5 references
- [8] doi:10.1098/rstb.2021.0512 [code]
- A deep neural network model of the primate superior colliculus for emotion recognition.Journal: Philosophical transactions of the Royal Society of London. Series B, Biological sciencesIn common: 4 references
- [9] doi:10.1073/pnas.2120581119 [code]
- Divisive normalization is an efficient code for multivariate Pareto-distributed environments.Journal: Proceedings of the National Academy of Sciences of the United States of AmericaIn common: 5 references
- [10] doi:10.1371/journal.pbio.3002375 [code]
- Human subcortical pathways automatically detect collision trajectory without attention and awareness.Journal: PLoS biologyIn common: 4 references
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 1 script, and 0 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:34c7aacda6097f53…
Add the badge to the code's README
If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.
Markdown
<!-- oscr-badge:start -->
[](https://openscicode.org/badge/repo/osf:hz7b9)
<!-- oscr-badge:end -->reStructuredText
.. oscr-badge:start
.. image:: https://openscicode.org/badge/repo/osf:hz7b9.svg
:target: https://openscicode.org/badge/repo/osf:hz7b9
:alt: OSCR
.. oscr-badge:endHTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/repo/osf:hz7b9"><img src="https://openscicode.org/badge/repo/osf:hz7b9.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.
Report a mismatch between the code and the paper · Report a code error (signed in)
Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.
Report a reproduction failure (signed in)
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
