Search This Blog

Monday, January 5, 2026

OBS - RedBlue 3d

 A Fun Thing To Do


I wanted to recreate a Red–Blue 3D (Anaglyph) video capability I lost.

Many years ago I purchased a Minoru 3D Web cam back in my 16-bit Windows days.


I still have it.   : )

If you have a few cameras sitting around, you can do the same thing using OBS Studio.



Here's How I Did It


The Equipment


I'm using a couple of Ubisoft cameras that operated well at 640x480. They do not have microphones. Speed and resolution are not a factor for me. They are cheap and do the job. 


You will want to set them so that the center of the cameras are about 6cm apart.

And, point them at your nose as close as you can. 

This take some patience and practice

Pick a meeting software and grab some images to compare, I found using two different meeting softwares, running side by side, one using the left camera and the second using the right camera, allowed to live point-tuning effectively.

When working with these cameras, you will be referencing them as if from the point of view of the eyes of the someone looking at you. The camera on the right, will be the red left eye of the person viewing you, and the camera on the left will the cyan right eye of the person viewing you.


The Software

You'll want to go to https://obsproject.com/ and download a version of OBS Studio for your system.

It's been a while since I did an initial load and configure of OBS. So I go nothing for that.

In OBS I created a Scene called RedBlue_Source


 I added two sources Right_Cyan and Left_Red.

And, finally, the RedBlue_Cropped scene is the final (polished?) output


Setup


Right_Cyan (the left camera)

Hit the plus (+) button (at the bottom) and choose Video Capture Device

Create New: Right_Cyan

Click OK

The Properties for Righ_Cyan will pop up.

This is what my properties look like...

I had to enable Deactivate when not showing.

I disabled Apply rotation data from the camera...

Click OK


* just a note here...

Deactivate when not showing may be needed due to the default USB drivers. Apparently, when switching scenes, a camera can get stuck on its initial frame (frozen). 


Add a Cyan Tint

Right Click the Right_Cyan source, and then on Filter.


Plus button, then Color Correction.

 

Name: Cyan_Tint

Click OK

Click the Select Color button.

Set HTML: #00ffff (zero zero foxtrot foxtrot foxtrot foxtrot)


Click OK

Adjust the Opacity to somewhere between .5 and .7   <--    IMPORTANT   ***

Adjust the other sliders to taste.

Here is what mine looks like... 



Fill the screen (optional)

This is a preference, but I like my sources to fill the screen. As the canvas (the output) is by default, 1920x1080, this tiny 640x480 video feed will only fill in a small portion of the screen. To demonstrate, observe the  red rectangle in the upper left corner, of this canvas (larger blue box around mostly everything. this is the default size on my video source unless I do something to it.


My Preference it to let it fill the screen. by default it will get letterboxed as needed.

Right click the source Right_Cyan > Transform > Fit to screen 



Left_Red (the right camera)

These Steps are very similar to the Right_Cyan steps.


Hit the plus button (at the bottom) and choose Video Capture Device

Create New: Left_Red

Click OK

The Properties for Left_Red will pop up.

Enable Deactivate when not showing.

Disabled Apply rotation data from the camera.

Click OK

Add a Red Tint

Right Click the Left_Red source, and then on Filter.

Plus button, then Color Correction.


 Name: Red_Tint

Click OK

 

Click the Select Color button.

Set HTML: #ff0000 (foxtrot foxtrot zero zero zero zero)

Click OK

 

Keep the Opacity at 1   <--   IMPORTANT   ***

Adjust the other sliders to taste.

Here is what mine looks like...


 

Fill the screen (optional)

Only do this if you did it for the Right_Cyan source

Right click the source Left_Red > Transform > Fit to screen


Adjust the layers

Layer Order

The sources can be dragged to ordered. but with the settings described as above, you will want Right_Cyan on top, then Left_Red

If you flip them, you may notice that the cyan layer is not visible.


 

Just drag the top source  to the bottom of the list, to flip them back.

Vertical and Horizontal Camera Adjustments

To ease eye strain, you will want to bump the cameras to as horizontally correct as you can determine. 

This feed is likely to cause some stress...


It works, because our brains are amazing things, but after a while it will be annoying.

By selecting the source then holding down the mouse button on the object on the canvas, you can use the arrow keys to make very small adjustments to the layers positions on the canvas.


In this example it puts the red-blue focus somewhere in the middle of my head. And as the vertical alignment is close, less strain on viewers.


Trim the Edges

After tweaking the larger positions I noticed that there was some extra red and cyan trim around the edge on my layers.


 

Right Click the scene RedBlue_Source > Filters


 

Plus Button > Crop/Pad


name: EdgeTrim

Click OK

 

At this point you'll have to play until you are happy with the results. Here is what mine looks like

 


Source Final...



Final Scene

Earlier I mentioned letterbox, OBS does not letterbox, or pillerbox, unless the source aspect ratio differs from the canvas AND you use “Fit to screen”. The last step...

Make a new scene 

Scenes box > Plus button

Name: RedBlue_Cropped

Click OK

The sources box will be empty,

Add a Source

Source box > Plus button > Scene


Add Existing > select RedBlue_Source

Click OK


In Sources, Right click the RedBlue_Source > Transform > Fit to screen




Final!




Use it


On installing the software,  OBS creates a virtual video source called OBS Virtual Camera that is usable by most meeting software.

In Zoom it looks like this...


When you are ready to start using it, Start OBS, select the scene RedBlue_Cropped,  and start the virtual camera (button in the lower right).


The start button toggles to Stop... 




Conclusion

There are actual video engineers out in the world that you should probably consult for advice on how to do this stuff. But, hopefully it gets you on a starting path.



You're done!   : )





P.S.   I still have the original packaging and glasses!   : )




Wednesday, November 12, 2025

Setting up Oracle Sqlplus on Windows, WSL Linux, and Mac OS

 


I was working through Oracle and PL-SQL training and was interested in seeing if I could set my work environment to allow work in WSL Bash on my Windows 11 workstation.

After downloading and setting up Oracle DB for Windows 11, and connecting via with SQL Developer and sqlplus and, I then turned my attention to WSL and my Mac.   : )


In Windows 11:


Windows Oracle SQL Developer connects by...
             hostname:localhost, port:1521, Service name: FREEPDB1   <<-- works!

DOS:    sqlplus system@//localhost:1521/FREEPDB1 works!   <<-- works!



Local Windows 11 prep...

You can get the instant client from Oracle (shown below), and installed, but it wont work without some modification to the local DB configuration and firewall, so do them first.

Oracle Configuration ...

The local Windows Oracle db configuration required a modification to D:\Oracle\dbhomeFree\network\admin\listener.ora. Mine looked similar to:

LISTENER =

  (DESCRIPTION_LIST =

    (DESCRIPTION =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))

      (ADDRESS = (PROTOCOL = TCP)(HOST = Toy4)(PORT = 1521))

      (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))

      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

    )

  )


*Toy4 is the current host.


Firewall configuration...

I also had to fix the windows host firewall with a new inbound rule like this:

## set up open 1521 port

d:/> wf.msc

name Oracle DB Inbound

TCP

PORT 1521

PUBLIC, PRIVATE


WSL BASH client...

Get the instant client software from Oracle for WSL Bash.

https://www.oracle.com/database/technologies/instant-client/downloads.html


Instant Client for Linux x86-64

https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html

d:\downloads\instantclient-basic-linux.x64-23.26.0.0.0.zip

SQL*Plus Package (ZIP)

d:\downloads\instantclient-sqlplus-linux.x64-23.26.0.0.0.zip


BASH Setup

I put all my WSL bash stuff in d:\oracle\WslBash 

$ cd /mnt/d/Oracle

$ mkdir WslBash

$ cd WslBash

$ unzip /mnt/d/downloads/instantclient-basic-linux.x64-*.zip

$ unzip /mnt/d/downloads/instantclient-sqlplus-linux.x64-*.zip

$ export ORACLE_HOME=/mnt/d/oracle/WslBash/instantclient_23_26

$ export LD_LIBRARY_PATH=$ORACLE_HOME

$ export PATH=$ORACLE_HOME:$PATH

    #to make it persistent add it to the .bashrc file


Test

sqlplus system@//Toy4:1521/FREEPDB1   <<-- Works!    : )


Mac OS on ARM (Zsh shell)


You can get the software needed from

https://www.oracle.com/database/technologies/instant-client/macos-arm64-downloads.html


Downloaded

Basic Package (DMG)

            instantclient-basic-macos.arm64-23.3.0.23.09-2.dmg

SQL*Plus Package (DMG)

            instantclient-sqlplus-macos.arm64-23.3.0.23.09.dmg


Install the software using Terminal & Finder...

Docs: https://www.oracle.com/database/technologies/instant-client/macos-arm64-downloads.html#install-ic


Install the Basic tools

% cd ~/Downloads

% hdiutil mount instantclient-basiclite-macos.arm64-23.3.0.23.09.dmg

#  This mounts as "-02": instantclient-basiclite-macos.arm64-23.3.0.23.09-02

% cd /Volumes/instantclient-basiclite-macos.arm64-23.3.0.23.09-02

% sh install_ic.sh

# this will create ~/Downloads/instantclient_23_3 with a bunch of files in it.

% hdiutil unmount instantclient-basiclite-macos.arm64-23.3.0.23.09.dmg

# if that does not work, then hit the eject button in Finder next to the volume

Add sqlplus

% hdiutil mount instantclient-sqlplus-macos.arm64-23.3.0.23.09.dmg

% cd /Volumes/instantclient-sqlplus-macos.arm64-23.3.0.23.09

% sh install_ic.sh

# this will add to ~/Downloads/instantclient_23_3 and you can see the sqlplise

% hdiutil unmount instantclient-sqlplus-macos.arm64-23.3.0.23.09.dmg

# if that does not work, then hit the eject button in Finder next to the volume

At this point you will have the instantclient_23_3 directory in the ~/Downloads dir.

I wanted it in opt so..

% mkdir /opt/Oracle

And, in Finder, I moved the Instant client dir to /Applications/Oracle

It looked like this...


Put it in the path.

% export PATH=$PATH:/opt/oracle/instantclient_23_3

# make sure to add it to your .zshrc or .bashrc file


Test

sqlplus system@//Toy4:1521/FREEPDB1   <<--- works!   : )




You're done!

 


Thursday, May 8, 2025

PostgreSQL Manual Install on Windows 11

 I had the hardest time getting Postgres upgraded from 16 to 17.

Short of a bare metal reload of my Windows 11 playground, I deleted everything!! Files, registry entries and anything that whiffed of ebd and postgres. 

IT TOOK HOURS!!!!!!   

... days    D . :


Afterwards, I did try the installer and was super disappointed that it failed to work. ... and did the cleanup again. grr.


I knew that there might be another way to install the db and after some quick internet searches found this handy article...

https://www.geeksforgeeks.org/postgresql-installing-postgresql-without-admin-rights-on-windows/

Thanks for the help!   : )



Get the Binaries Download

I went to to

https://www.postgresql.org/download/

Clicked on Windows

https://www.postgresql.org/download/windows/

Found, and clicked on "zip archive"

https://www.enterprisedb.com/download-postgresql-binaries

Clicked on Win x86-64

Which put postgresql-17.4-2-windows-x64-binaries.zip in my download directory.

Or in Powershell...

# Set url and destination

$URL = 'https://sbp.enterprisedb.com/getfile.jsp?fileid=1259504'

$output = "d:\downloads\d:\downloads\postgresql-17.4-2-windows-x64-binaries.zip"

# transfer the file with BITS

Start-BitsTransfer -Source $url -Destination $output


Put the files in a useful place

I open the archive, and found the pgsql folder.

I copied the contents of the pgsql folder into my D:\Postgres directory

Or in Powershell...

# Define Zip to work with

$ZipPath = "d:\downloads\postgresql-17.4-2-windows-x64-binaries.zip"

# Define file path as a source or destination

$FilePath = D:\Postgres

# Expand entire zip to a path

Expand-Archive -Path $zipPath -DestinationPath $FilePath -Force

That only kinda does it. The resulting folder is d:\Postgres\pgsql. so bin, doc, lib, and the other dirs are in pgsql. I want them all one level up in d:\Postgres so I did it like this...

# expand a specific folder from a zip to a path

Add-Type -AssemblyName System.IO.Compression.FileSystem

$ZipPath = "d:\downloads\postgresql-17.4-2-windows-x64-binaries.zip"

$Subfolder = "pgsql/"

$FilePath = "D:\Postgres"

$Subfolder = "pgsql/"

$FilePath = "D:\Lesley\bin"

$zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)

foreach ($entry in $zip.Entries) {

if ($entry.FullName.StartsWith($Subfolder)){

write-host $entry.FullName

$outPath = Join-Path $FilePath ($entry.FullName.Substring($Subfolder.Length + 1))

write-host ("   item: " + $outPath)

$outDir = Split-Path -Parent $outPath

write-host ("   out dir: " + $outDir )

if (-not (Test-Path -Path $outDir -PathType Container))

New-Item -Path $outDir -ItemType Directory -Force | Out-Null

write-host ("       + New Path: " + $outDir)

}

[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $outPath, $true)

}

}

The resulting dir structure looks like this...

d:\Postgres\

+ bin

+ doc

+ lib

+ ...

A simple drag and drop will also do it.   : )


Make a data directory

I'm picking d:\postgresql\data

new-item -path d:\postgresql -name data -itemtype directory


Make sure to have permissions on the directory tree.

While you can do this from file explorer (It's pretty easy), I (unfortunately) like to do thing from the command ine. It's a preference.   : )


In Powershell...

$FilePath = "D:\Postgresql"

$user = "NT AUTHORITY\NETWORK SERVICE"

$permissions = "FullControl"  # Options: FullControl, ReadAndExecute, Modify,

# Get the folder's current ACL

$acl = Get-Acl $FilePath 

# Create a new access rule

$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($user, $permissions, "ContainerInherit,ObjectInherit", "None", "Allow")

# Add the access rule to the ACL

$acl.SetAccessRule($accessRule)

# Apply the updated ACL to the folder

Set-Acl -Path $FilePath -AclObject $acl

# Recursively apply the ACL to subfolders and files

Get-ChildItem -Path $FilePath -Recurse | ForEach-Object {

Set-Acl -Path $_.FullName -AclObject $acl

}

Test... This generates a lot of output. I captured it to a test.txt file and perused it in a text editor.

$FilePath = "F:\Postgresql"

$user = "NT AUTHORITY\NETWORK SERVICE"

$permissions = "FullControl,Allow"

$oFile = "f:\test.txt"


$dirs = $null; $dirs = Get-ChildItem -Path $FilePath -Directory -Recurse

$countDirs = $null; $countDirs = $dirs.count

$lencountDirs = $null; $lencountDirs = $countDirs.tostring().length

$countLoop = 0

Foreach ( $dir in $dirs ){

$countLoop++

$Acl = Get-Acl -Path $dir

$AccessRules = $Acl.Access | Where-Object {$_.IdentityReference -like $User} | select FileSystemRights, AccessControlType

$oStatus = $null; $oStatus = $countLoop.tostring("D$lencountDirs") + '/' + $countDirs + ' dir: ' + $dir

Write-Host $oStatus

$oCSV = $null; $oCsv = $AccessRules | ConvertTo-Csv -NoTypeInformation

$oCSVText = $null; $oCSVText = (($oCSV | Select-Object -Skip 1) -join ';' -replace '"')

$oText = $null; $oText = '' + $dir + '...' + "`r`n        " + $oCSVText

Add-Content -Path $oFile -Value $oText

}

'PermissionCount: ' + (Select-String -LiteralPath $oFile -Pattern $permissions -AllMatches).Matches.Count


The PermissionCount shoud be a multiple of  the number of directories. My results looked like this...




Set the Path

In Settings > System > About > Advanced system settings... open the System Properties dialog

In the System Properties dialog > Advanced tab > Environment Variables button... opens the Environment Variables dialog

In the Environment Variables > system variables, look for, and click on "Path" > Edit button... this open the Edit environment variable dialog. If the your postgres bin's path is missing from the list you may want to add it.  mine looks like this...


Click ok and restart your system when you are ready to do so.


In Powershell, similar to this...

# Get the current PATH : MACHINE

$currentPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)

# Define path value to add or remove

$PathValue = "D:\PostgreSQL\bin"  

# ADD a value

$newpath = "$currentPath;$PathValue"

## Apply change

# Set the new PATH : MACHINE

[System.Environment]::SetEnvironmentVariable("Path", $newPath, [System.EnvironmentVariableTarget]::Machine)

# Observe the change

[System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)

# Restart the computer

restart-computer


Verify the installation

[System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)

postgres -V

psql -V


Initialize the database

initdb -D D:\PostgreSQL\data -U postgres -E utf8

Afterwards, just to be careful: make a backup of the pg_hba.conf and postgresql.conf. I just copied mine like this...

pg_hba.conf => pg_hba.conf-0Init

postgresql.conf => postgresql.conf-0Init

This makes restarting and resetting changes easier. If restoring these files fails to reset your environment, you can delete the data directory and run the initdb again.

The "-U postgres" is typical, your initial account can be whatever you want. Just remember to know what it is.   : )


Start the server

pg_ctl -D D:\PostgreSQL\data -l logfile start

if you need to stop it for some reason, it's...

pg_ctl -D D:\PostgreSQL\data stop


Access the Database With pgAdmin

Start pgAdmin 

Add a New Server

General>Name: LocalPostgreSQL

Connaction>Host name/address: localhost

Save


LocalPostgreSQL should appear in your Object Explorer and after a few moments you may see graphing similar to the following...



[Optional] Set the postgres password

In Object Explorer  Servers > LocalPostgreSQL > Login/Group Roles > righ click postgres > Properties > definition > Password


Set your password and click Save


if you wanted to do this from the command line then it may look something like this...


psql -U postgres 

ALTER USER postgres WITH PASSWORD 'new_password';

postgres=# \q

Test the Password

To test the password locally you will have to modify the the pg_hba.conf to use passwords. By default the configuration trust local connections.


Modify pg_hba.conf

Find the "host all all trust" line and change it to "host all all md5"

Notice that I also added the local ip ranges to md5 as well. It may not be needed for your implementation.

Save the file.


Stop and restart the db server


pg_ctl -D D:\PostgreSQL\data stop

pg_ctl -D D:\PostgreSQL\data -l logfile start

Restart pgAdmin4 and open the db

Use that new password.   : )



Connection from Other Devices

If you want connectivity and accessibility from another device on your network, you'll have to make sure your firewall allows connections to the port (PostgreSQL defaults to 5432) and add lines to the postgresql.conf and pg_hba.conf to allow the connections. postgresql.conf allow general configuration while pg_hba.conf allows finer control.

Fix the Firewall.

Windows Start > Settings > Privacy & Security > Firewall & network protection > Advanced settings

New Rule

Type of rule: Port

Protocol and Ports: TCP

Specific local Ports: 5432

Action: Allow the connection

Profile: [all]

Name: PostgreSQL in port 5432

 

In Powershell...

New-NetFirewallRule -DisplayName "PostgreSQL in port 5432" -Direction Inbound -LocalPort 5432 -Protocol TCP -Action Allow

This is a little too loose for me, so tighten it up as you can.


Modify data\postgresql.conf to allow the db to listen for connections

listen_addresses = '*'

Notice that you can make this tighter as needed.

Modify the allowed connections in data\pg_hba.conf

host    all             all              192.168.1.0/24         md5


Most home networks only have the one, 192.168.1.0 network. Check yours and add as needed.


Go Test!   : D




You're Done!   : )