Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Count and Size
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def whitePixelAreas(i_flocBounds, j_flocBounds, img):


# Example usage
img = cv2.imread("pureblack.jpg")
img = cv2.imread("openCV/flocs/Image \32346.jpg")
count_and_size_flocs(img)


Expand Down
138 changes: 137 additions & 1 deletion application/visual.py
Original file line number Diff line number Diff line change
@@ -1 +1,137 @@
#Hi everyone -Erika
import glob
import wx
import eyed3


# Editing the code from a tutorial
class Mp3Panel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
main_sizer = wx.BoxSizer(wx.VERTICAL)
self.row_obj_dict = {}

self.list_ctrl = wx.ListCtrl(
self, size=(-1, 100),
style=wx.LC_REPORT | wx.BORDER_SUNKEN
)
self.list_ctrl.InsertColumn(0, 'Name', width=140)
self.list_ctrl.InsertColumn(1, 'Floc Count', width=140)
self.list_ctrl.InsertColumn(2, 'Floc Size', width=200)
main_sizer.Add(self.list_ctrl, 0, wx.ALL | wx.EXPAND, 5)
edit_button = wx.Button(self, label='Edit')
edit_button.Bind(wx.EVT_BUTTON, self.on_edit)
main_sizer.Add(edit_button, 0, wx.ALL | wx.CENTER, 5)
self.SetSizer(main_sizer)

def on_edit(self, event):
selection = self.list_ctrl.GetFocusedItem()
if selection >= 0:
mp3 = self.row_obj_dict[selection]
dlg = EditDialog(mp3)
dlg.ShowModal()
self.update_mp3_listing(self.current_folder_path)
dlg.Destroy()

def update_mp3_listing(self, folder_path):
self.current_folder_path = folder_path
self.list_ctrl.ClearAll()

self.list_ctrl.InsertColumn(0, 'Artist', width=140)
self.list_ctrl.InsertColumn(1, 'Album', width=140)
self.list_ctrl.InsertColumn(2, 'Title', width=200)
self.list_ctrl.InsertColumn(3, 'Year', width=200)

mp3s = glob.glob(folder_path + '/*.mp3')
mp3_objects = []
index = 0
for mp3 in mp3s:
mp3_object = eyed3.load(mp3)
self.list_ctrl.InsertItem(index,
mp3_object.tag.artist)
self.list_ctrl.SetItem(index, 1,
mp3_object.tag.album)
self.list_ctrl.SetItem(index, 2,
mp3_object.tag.title)
mp3_objects.append(mp3_object)
self.row_obj_dict[index] = mp3_object
index += 1


class Mp3Frame(wx.Frame):

def __init__(self):
wx.Frame.__init__(self, parent=None,
title='Mp3 Tag Editor')
self.panel = Mp3Panel(self)
self.create_menu()
self.Show()

def create_menu(self):
menu_bar = wx.MenuBar()
file_menu = wx.Menu()
open_folder_menu_item = file_menu.Append(
wx.ID_ANY, 'Open a File',
'Open a folder with MP3s'
)
menu_bar.Append(file_menu, '&File')
self.Bind(
event=wx.EVT_MENU,
handler=self.on_open_file,
source=open_folder_menu_item,
)
self.SetMenuBar(menu_bar)

def on_open_file(self, event):
# otherwise ask the user what new file to open
with wx.FileDialog(self, "Open JPG file", wildcard="*.jpg",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:

if fileDialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind

# Proceed loading the file chosen by the user
pathname = fileDialog.GetPath()
try:
with open(pathname, 'r') as file:
# self.doLoadDataOrWhatever(file)
print(file)
except IOError:
wx.LogError("Cannot open file '%s'." % file)


class EditDialog(wx.Dialog):
def __init__(self, mp3):
title = f'Editing "{mp3.tag.title}"'
super().__init__(parent=None, title=title)
self.mp3 = mp3
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
self.artist = wx.TextCtrl(
self, value=self.mp3.tag.artist)
self.add_widgets('Artist', self.artist)
self.album = wx.TextCtrl(
self, value=self.mp3.tag.album)
self.add_widgets('Album', self.album)
self.title = wx.TextCtrl(
self, value=self.mp3.tag.title)
self.add_widgets('Title', self.title)
btn_sizer = wx.BoxSizer()
save_btn = wx.Button(self, label='Save')
save_btn.Bind(wx.EVT_BUTTON, self.on_save)
btn_sizer.Add(save_btn, 0, wx.ALL, 5)
btn_sizer.Add(wx.Button(
self, id=wx.ID_CANCEL), 0, wx.ALL, 5)
self.main_sizer.Add(btn_sizer, 0, wx.CENTER)
self.SetSizer(self.main_sizer)

def on_save(self, event):
self.mp3.tag.artist = self.artist.GetValue()
self.mp3.tag.album = self.album.GetValue()
self.mp3.tag.title = self.title.GetValue()
self.mp3.tag.save()
self.Close()


if __name__ == '__main__':
app = wx.App(False)
frame = Mp3Frame()
app.MainLoop()
6 changes: 4 additions & 2 deletions camera/camera.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from PyQt5.QtGui import *
from PyQt5.QtMultimedia import QCamera, QCameraInfo, QCameraImageCapture
from PyQt5.QtMultimediaWidgets import QCameraViewfinder
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtPrintSupport import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
# from PyQt5.QtMultimedia import *
# from PyQt5.QtMultimediaWidgets import *
#
import os
import sys
Expand Down
43 changes: 43 additions & 0 deletions camera/camerawithwx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import cv2
import wx


class Camera (wx.Panel):
def __init__(self, *args, **kw):
super (Camera, self).__init__(*args, **kw)
self.setWindowTitle("Floc App")
self.initUI()
width = self.width()
height = self.height()
self.setGeometry(10, 10, 800, 400)

self.show()

def InitUI(self):
self.init_menuBar()
self.init_statusBar()
self.init_camera()
self.init_cameraBar()
self.init_filterSideBar()

self.show()

def init_menuBar(self):
mainMenu = self.menuBar()
mainMenu.setNativeMenuBar(False)
fileMenu = mainMenu.addMenu('File')
viewMenu = mainMenu.addMenu('View')
toolMenu = mainMenu.addMenu('Tools')

self.init_fileMenu(fileMenu)
self.init_viewMenu(viewMenu)
self.init_toolMenu(toolMenu)

def init_camera(self):
self.available_cameras = QCameraInfo.availableCameras()
if not self.available_cameras:
pass
self.viewfinder = QCameraViewfinder()
self.viewfinder.show()
self.setCentralWidget(self.viewfinder)
self.select_camera(0)
179 changes: 179 additions & 0 deletions count_and_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@


# Written by Richard Yu (ry275@cornell.edu)

import cv2
import numpy as np


# Returns: A 2-dimensional list/grid that contains value True or False, which denotes whether a coordinate is a
# "near-white" pixel (R >= 225, G >= 225, B >= 225) or not
# Requires: an RGB 3-dimensional list/picture
def whitePixels(grid):
res = [[True for y in range(len(grid[0]))] for x in range(len(grid))]
for i in range(len(grid)):
for j in range(len(grid[i])):
curPixel = grid[i][j]
if curPixel < 255:
res[i][j] = False
#for rgb in curPixel:
#if rgb < 225:
#res[i][j] = False
#break
return res



import sys

# Returns: the count of non-zero (black) pixels for an inputted picture/3-dimensional list
# Requires: a 3-dimensinoal list/picture
def nonBlackPixels(img):
return cv2.countNonZero(img)

'''
Purpose:
- Given an image of a floc, will apply a set of image proccessing Functions
to identify in focus flocs from the background.
Parameters:
- A .jpg image read in as a grayscale image i.e cv2.imread('path',0)
Returns:
- A processed .jpg image
Raises:
-
'''
def flocID(img):
blur = cv2.GaussianBlur(img, (5,5), 10)
t = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV,9,7)
kernel = np.ones((4,4),np.uint8)
dilation = cv2.dilate(t,kernel,iterations = 2)
opened = cv2.morphologyEx(dilation, cv2.MORPH_OPEN, kernel)
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
return closed

# Returns: scales down img's [i],[j] dimensions by a factor of 5, effectively shrinking the image to 1/25 its original size
# Requires: a 3-dimensional list/picture
def shrink5x(img):
shrunk = cv2.resize(img,None,fx=.2, fy=.2, interpolation = cv2.INTER_CUBIC)
return shrunk



# Returns: a 5-tuple, containing the count of "near-white" pixel (R >= 225, G >= 225, B >= 225) islands, a
# list containing the counts of near-white pixels for each individual island, the total count of near-white pixels,
# the total count of non-black pixels, and a string explaining if there is a noticeable difference between the
# sum of individual near-white pixel counts and the total count of non-black pixels.
# Requires: an RGB 3-dimensional list/picture
def count_and_size_flocs(img):

# Increases the recursive call stack limit to 100,000 to ensure
# that the method does not give a "recursion/stack overflow" error
sys.setrecursionlimit(100000)

# Shrinks img to reduce the number of pixels this method has to iterate over
shrunk = shrink5x(img)
shrunk = whitePixels(shrunk)
islands = 0

i_flocBounds = []
j_flocBounds = []

for i in range(len(shrunk)):
for j in range(len(shrunk[i])):
if shrunk[i][j] == True:
iCoords = [i]
jCoords = [j]
part_of_island(i, j, shrunk, iCoords, jCoords)
i_flocBounds_raw = ([min(iCoords) * 5 - 5,max(iCoords) * 5 + 5])
j_flocBounds_raw = ([min(jCoords) * 5 - 5, max(jCoords) * 5 + 5])
if (i_flocBounds_raw[0] <= 0):
i_flocBounds_raw[0] = 0
if (i_flocBounds_raw[1] >= len(img) - 1):
i_flocBounds_raw[1] = len(img) - 1
if (j_flocBounds_raw[0] <= 0):
j_flocBounds_raw[0] = 0
if (j_flocBounds_raw[1] >= len(img[0]) - 1):
j_flocBounds_raw[1] = len(img[0]) - 1
i_flocBounds.append(i_flocBounds_raw)
j_flocBounds.append(j_flocBounds_raw)
islands += 1

#print(i_flocBounds, j_flocBounds)
flocAreas = whitePixelAreas(i_flocBounds, j_flocBounds, img)
nonBlacks = nonBlackPixels(img)
flocAreasTotal = sum(flocAreas)
description = ""
if (abs(flocAreasTotal - nonBlacks) >= (nonBlacks/5)):
description = "There is GREATER THAN a 20% discrepancy between the sum of individual near-white pixel counts and the total count of non-black pixels! There are many non-black AND non-near-white pixels!"
else:
description = "There is LESS THAN a 20% discrepancy between the sum of individual near-white pixel counts and the total count of non-black pixels."
return islands, flocAreas, nonBlacks, description



# Returns: nothing, but sets all adjacent near-white pixels to black pixels and appends the coordinates of adjacent
# near-white pixels to a list of [i] coordinates and a list of [j] coordinates
# Requires: a single [i][j] coordinate of a near-white pixel for a 3-dimensional list/picture,
# a T/F 2-dimensional list/grid, a list of [i] cooridinates for adjacent near-white pixels,
# and a list of [j] coodinates for adjacent near-white pixels.
def part_of_island(i, j, grid, iCoords, jCoords):
if i < 0 or j < 0 or i == len(grid) or j == len(grid[i]) or (grid[i][j] == False):
return
else:
grid[i][j] = False
iCoords.append(i)
jCoords.append(j)
part_of_island(i,j+1,grid, iCoords, jCoords)
part_of_island(i,j-1,grid, iCoords, jCoords)
part_of_island(i+1,j,grid, iCoords, jCoords)
part_of_island(i-1,j,grid, iCoords, jCoords)
part_of_island(i+1,j+1,grid, iCoords, jCoords)
part_of_island(i+1,j-1,grid, iCoords, jCoords)
part_of_island(i-1,j+1,grid, iCoords, jCoords)
part_of_island(i-1,j-1,grid, iCoords, jCoords)



# Returns: a 2-dimensional list that is a "subgrid" of the inputted 2-dimensional list
# Requires: a min [j] and max [j] coordinate, a min [i] and max [i] coordinate, and a 2-dimensional list (a grid)
def getsubgrid(j1, i1, j2, i2, grid):
return [item[j1:j2] for item in grid[i1:i2]]



# Returns: a list containing the counts of near-white pixels for every "near-white pixel island" in a picture
# Requires: a list of tuples containing the [i] coordinate bounds and a list of tuples containing
# the [j] coordinate bounds that locates each near-white pixel island for an inputted RGB 3-dimensional list/picture.
def whitePixelAreas(i_flocBounds, j_flocBounds, img):
subgrids = []
floc = 0
for flocBound in i_flocBounds:
i_Bounds = i_flocBounds[floc]
j_Bounds = j_flocBounds[floc]
subgrids.append(getsubgrid(j_Bounds[0], i_Bounds[0], j_Bounds[1], i_Bounds[1],img))
floc = floc+1

whitePixelGrids = []
for subgrid in subgrids:
whitePixelGrids.append(whitePixels(subgrid))

flocAreas = []
for img in whitePixelGrids:
pixels = 0
for i in range(len(img)):
for j in range(len(img[i])):
if img[i][j] == True:
pixels = pixels + 1
flocAreas.append(pixels)
return flocAreas



# Example usage
img = cv2.imread("openCV/flocs/Image 32346.jpg", 0)
processed_img = flocID(img)
print(count_and_size_flocs(processed_img))



Loading