Color Palette reverses: Assigning specific color to one cluster and a different color to another cluster in KMeans. (GEE - PythonAPI) - google-colaboratory

I am trying to cluster the image using GEE API into 2 classes and the algorithm is working fine but when I am visualizing, the colors reverse. That is, for year1 -> class1: green, class2: yellow but for year2 the colors revert for the same lines of code. Year2 -> class1: yellow, class2: green.
Code:
def kmeans(year):
training = year.sample(**{
'region': country,
'scale': 30,
'numPixels': 5000
})
#Instantiate the clusterer and train it.
clusterer = ee.Clusterer.wekaKMeans(2).train(training)
#Cluster the input using the trained clusterer.
result = year.cluster(clusterer)
return result
###VISUALIZATION
def vis_kmeans(previous_year, next_year):
Map = geemap.Map()
#Display the clusters with random colors.
kmeansVis = {'min':-1, 'max':1, 'palette':['green', 'yellow']}
Map.addLayer(previous_year, kmeansVis, 'year1')
Map.addLayer(next_year, kmeansVis, 'year2')
Map.centerObject(country, 10) #to adjust the zoom center
return Map
Output Year1:
Output Year2:
Why are the colors reverting? How do I avoid it?

Related

Jumbled text on pymupdf textbox creation

I've created a textbox redaction on pymupdf that seems to work perfectly.
But when viewing it on Mac OS, the numbers appear incorrect and jumbled. Anyone have an idea what could change a pdf's view for an identical file across OS?
def apply_overlay(
page, new_area, variable, fontsize, color, align, font, is_column=False
):
col = fitz.utils.getColor("white")
variable_area = copy.deepcopy(new_area)
variable_area.y1 = new_area.y0 + fontsize + 3
redaction = page.addRedactAnnot(
variable_area, fill=col, text=" "
) # flags not available
else:
redaction = page.addRedactAnnot(
new_area, fill=col, text=" "
)
page.apply_redactions(images=fitz.PDF_REDACT_IMAGE_NONE)
writer = fitz.TextWriter(page.rect, color=color)
assignment
writer.fill_textbox(
new_area, variable, fontsize=fontsize, warn=True, align=align, font=font
)
writer.write_text(page)
# To show what happened, draw the rectangles, etc.
shape = page.newShape()
shape.drawRect(new_area) # the rect within which we had to stay
shape.finish(stroke_opacity=0) # show in red color
shape.commit()
shape = page.newShape()
shape.drawRect(writer.text_rect) # the generated TextWriter rectangle
shape.drawCircle(writer.last_point, 2) # coordinates of end of text
shape.finish(stroke_opacity=0) # show with blue color
shape.commit()
return shape

Downsample array based on sliding window indices

I am trying to downsample or reduce the resolution of a 3D array only on the first two axes. For example, if the array size is 40x50x300, downsampling it with a degree of 2 will make it 20x25x300
for this purpose, I have found a function in scikit-image
def create_img(nX, nY, nMZ):
"this function creates a demo array"
img = np.zeros((nX,nY,nMZ))
img_sp = np.arange(nX*nY).reshape(nX, nY) + 1
for r in range(img.shape[0]):
for c in range(img.shape[1]):
img[r,c,:] = img_sp[r,c]
return img
image = create_img(7, 5, 10)
Now every pixel in the image(2D) has corresponding values on the z axis.
from skimage.measure import block_reduce
img_block = block_reduce(image, block_size=(2, 2, 1), cval=0, func=np.min)
now, the block_reduce function will take every minimum value in sliding 2x2 window and downsample the image on the x and y-axis.
If func arg is changed to np.max it will take the maximum value in the 2x2 window. The other supporting func are np.mean, np.median and so...
But I want to take XY values based on location/indices for example 0th element on 2x2 or max indice elements.
How to achieve that?

Pytesseract OCR with different colors

I am trying to read this type of image with pytesseract but I have some issue with the part in yellow because the color transformation that works for other chracters won't work for those in yellow boxes. Also I want to keep the " numbers fo each row well split.
Any idea how I could manage that?
Thanks
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# invert = 255 - thresh
# OCR
data = pytesseract.image_to_string(thresh, config="--psm 6")
print(data)
cv2.imshow("thresh", thresh)
# cv2.imshow("invert", invert)
cv2.waitKey()
Returns: '> SKAPOVALOY 4 (15\nRINDERKNECH 6 [EY 15\n'

Tesseract and multiple line license plates: How can I get characters from a two line license plate?

i tried getting individual characters from the image and passing them through the ocr, but the result is jumbled up characters. Passing the whole image is at least returning the characters in order but it seems like the ocr is trying to read all the other contours as well.
example image:
Image being used
The result : 6A7J7B0
Desired result : AJB6779
The code
img = cv2.imread("data/images/car6.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# resize image to three times as large as original for better readability
gray = cv2.resize(gray, None, fx = 3, fy = 3, interpolation = cv2.INTER_CUBIC)
# perform gaussian blur to smoothen image
blur = cv2.GaussianBlur(gray, (5,5), 0)
# threshold the image using Otsus method to preprocess for tesseract
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
# create rectangular kernel for dilation
rect_kern = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
# apply dilation to make regions more clear
dilation = cv2.dilate(thresh, rect_kern, iterations = 1)
# find contours of regions of interest within license plate
try:
contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
except:
ret_img, contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# sort contours left-to-right
sorted_contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0])
# create copy of gray image
im2 = gray.copy()
# create blank string to hold license plate number
plate_num = ""
# loop through contours and find individual letters and numbers in license plate
for cnt in sorted_contours:
x,y,w,h = cv2.boundingRect(cnt)
height, width = im2.shape
# if height of box is not tall enough relative to total height then skip
if height / float(h) > 6: continue
ratio = h / float(w)
# if height to width ratio is less than 1.5 skip
if ratio < 1.5: continue
# if width is not wide enough relative to total width then skip
if width / float(w) > 15: continue
area = h * w
# if area is less than 100 pixels skip
if area < 100: continue
# draw the rectangle
rect = cv2.rectangle(im2, (x,y), (x+w, y+h), (0,255,0),2)
# grab character region of image
roi = thresh[y-5:y+h+5, x-5:x+w+5]
# perfrom bitwise not to flip image to black text on white background
roi = cv2.bitwise_not(roi)
# perform another blur on character region
roi = cv2.medianBlur(roi, 5)
try:
text = pytesseract.image_to_string(roi, config='-c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ --psm 8 --oem 3')
# clean tesseract text by removing any unwanted blank spaces
clean_text = re.sub('[\W_]+', '', text)
plate_num += clean_text
except:
text = None
if plate_num != None:
print("License Plate #: ", plate_num)
For me psm mode 11 worked able to detect single line and multi as well
pytesseract.image_to_string(img, lang='eng', config='--oem 3 --psm 11').replace("\n", ""))
11 Sparse text. Find as much text as possible in no particular order.
If you want to extract license plate number from two rows you can replace following line:
sorted_contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0] + cv2.boundingRect(ctr)[1] * img.shape[1] )
with
sorted_contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0])

CGAL : Can I use alpha shape to simplify a path?

I would like to get the outter part of a robot trajectory (the boundaries of this trajectory).
I read in several posts that the best way to retrieve the boundary of a point cloud is to use alpha shapes.
So I use the alpha shape implementation of CGAL.
Above picture repressent :
Blue dot : The robot trajectory
Red cross : Vertexes of the optimal alpha shape
Cyan edges : Edges of the optimal alphashape.
Optimal alpha is according to the CGAL documentation the alpha for which :
All data points are either on the boundary or in the interior of the regularized version of the alpha shape.
The number of solid component of the alpha shape is equal to or smaller than 1.
If I increase alpha, I got the convex hull (as expected).
But I can't find an alpha that will give me the following boundary (the black one in the figure bellow) :
So my question is :
Does the black shape in figure above can be found thanks to alpha shapes with the blue point as input ?
For those who wants to see how to use the CGAL python binding to generate alpha shapes, here is my code :
def computeAlphaShape(val):
alpha_shape = Alpha_shape_2(points, 10000.0)
it = alpha_shape.find_optimal_alpha(1)
optimal_alpha = it.next()
alpha_shape.set_alpha(val)
print("Optimal alpha : " + str(optimal_alpha) + " current alpha : " + str(val))
if val == 0:
salpha.set_val(optimal_alpha)
return
print("Solid components : " + str(alpha_shape.number_of_solid_components()))
drawResult(alpha_shape)
salpha.on_changed(computeAlphaShape)
def drawResult(alpha_shape):
ax.clear()
ax.plot(X, Y, 'ob')
edges = alpha_shape.alpha_shape_edges()
while edges.hasNext():
eresX = []
eresY = []
edge = edges.next()
segment = alpha_shape.segment(edge)
eresX.append(segment.source().x())
eresY.append(segment.source().y())
eresX.append(segment.target().x())
eresY.append(segment.target().y())
classe = alpha_shape.classify(edge)
color = 'g-'
if classe == EXTERIOR:
color = 'b-'
elif classe == INTERIOR:
color = 'r-'
elif classe == SINGULAR:
color = 'y-'
elif classe == REGULAR:
color = 'c-'
ax.plot(eresX, eresY, color)
vertices = alpha_shape.alpha_shape_vertices()
v_res_x =[]
v_res_y = []
while vertices.hasNext():
vertex = vertices.next()
v_res_x.append(vertex.point().x())
v_res_y.append(vertex.point().y())
ax.plot(v_res_x, v_res_y, '+r')
For such a task I would use the simplification package if the already have the segments and the 2D reconstruction package is you only have points.
Alpha-shape will work well only if the density of the points is uniform, by picking all edges that are not EXTERIOR. Alpha should be the squared distance between 2 points on the trajectory (just a bit more to be sure the edge is picked). I'm not even sure about what will be the outcome if you have some parts with a small local feature size. In such a case, only SINGULAR and REGULAR edges should be picked.