Apologies for a basic question. I have checking out the for loops here and here and for example if we analyse the first code :
for(int i = 0; i < CFDataGetLength(pixelData); i += 4) {
pixelBytes[i] // red
pixelBytes[i+1] // green
pixelBytes[i+2] // blue
pixelBytes[i+3] // alpha
}
The variable i is being incremented from 0 to the length of the array pixelData, in steps of 4.
However how does pixelBytes[i+3] access the alpha channel of the image? So for example if i=5, how does pixelBytes[5+3] equal the alpha channel instead of just accessing the 8th element of pixelBytes?
If i starts at zero and is incremented by 4 each time, how can it ever equal 5?
Presumably, the structure is stored with each channel occupying one byte, first red, then green, then blue, then alpha, then red again and so on. The for loop mimics this structure by increment i by four each time, so if the first time through pixelBytes[i+1] is the first green value, the second time through it will be four bytes later and thus the second green value.
Sometimes it helps to unrool the loop on a sheet of paper
// First pixel
RGBA
^ Index 0 = i(0) + 0
^ Index 1 = i(0) + 1
^ Index 2 = i(0) + 2
^ Index 3 = i(0) + 3
i + 4
// Second pixel
RGBA RGBA
^ Index 4 = i(4) + 0
^ Index 5 = i(4) + 1
^ Index 6 = i(4) + 2
^ Index 7 = i(4) + 3
i + 4
// Third pixel
RGBA RGBA RGBA
^ Index 8 = i(8) + 0
^ Index 9 = i(8) + 1
^ Index 10 = i(8) + 2
^ Index 11 = i(8) + 3
You have colours stored in the RGBA format. In the RGBA format, one colour is stored in 4 bytes, the first byte being the value for red (R), second is green (G), third is blue (B), and last is alpha (A).
Your own code explains this pretty well in its comments:
pixelBytes[i] // red
pixelBytes[i+1] // green
pixelBytes[i+2] // blue
pixelBytes[i+3] // alpha
It is important to note though, that if i is not a multiple of 4, you're not going to be reading the colours correctly anymore.
While the code isn't there, it is likely that pixelBytes is an array of size equal to the total number of colours times 4, which is the same thing as the number of total bytes used to represent the colours (since each colour is stored in 4 bytes)
A typical 32 bit pixel consists of four channels, alpha, red, green and blue.
My guess is that pixelbytes is a bytebuffer of these, so:
pixelbuffer[0] = r
pixelbuffer[1] = g
pixelbuffer[2] = b
pixelbuffer[3] = a
as your code says.
On each iteration, it adds four bytes (8 bit * 4 = 32 bit) to the counter, equaling the offset to the next 32bit pixel. The individual components can be accessed through a byte offset (i + <0-3>).
Related
I am making a Pong game in Delphi.
Paddle.Left := X - Paddle.Width div 2;
Paddle.Top := ClientHeight - Paddle.Height - 2;
I expect the output of 5/2 to be 2.5, but the actual output is 2.
The div operator performs integer division (5 div 2 = 2, throwing away the decimal .5), whereas the / operator performs floating point division (5 / 2 = 2.5).
In VCL, a control's Left, Top, Width, and Height values are expressed using whole integers, not floating point numbers.
In FMX, a control's Position and Size values are expressed using floating point numbers.
div is the integer division operator. It is a binary operator that takes two integers, and returns an integer, the truncated value of the division. For instance,
0 div 3 = 0
1 div 3 = 0
2 div 3 = 0
3 div 3 = 1
4 div 3 = 1
5 div 3 = 1
6 div 3 = 2
...
If you want to perform a floating-point division, you need to use the / operator:
0 / 3 = 0
1 / 3 = 0.33333333333333
2 / 3 = 0.66666666666666
3 / 3 = 1
4 / 3 = 1.33333333333333
5 / 3 = 1.66666666666666
6 / 3 = 2
...
Of course, the result cannot be stored in an integer variable. If you eventually need an integer value to specify a pixel on the screen, you need to round the floating-point value to an integer (using the Round function).
I am trying to read image from the text.
I am getting better result if I break the images into small chunks but the problem is when i try to split the image it is cutting/slicing my characters.
code I am using :
from __future__ import division
import math
import os
from PIL import Image
def long_slice(image_path, out_name, outdir, slice_size):
"""slice an image into parts slice_size tall"""
img = Image.open(image_path)
width, height = img.size
upper = 0
left = 0
slices = int(math.ceil(height/slice_size))
count = 1
for slice in range(slices):
#if we are at the end, set the lower bound to be the bottom of the image
if count == slices:
lower = height
else:
lower = int(count * slice_size)
#set the bounding box! The important bit
bbox = (left, upper, width, lower)
working_slice = img.crop(bbox)
upper += slice_size
#save the slice
working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
count +=1
if __name__ == '__main__':
#slice_size is the max height of the slices in pixels
long_slice("/python_project/screenshot.png","longcat", os.getcwd(), 100)
Sample Image : The image i want to process
Expected/What i am trying to do :
I want to split every line as separate image without cutting the character
Line 1:
Line 2:
Current result:Characters in the image are cropped
I dont want to cut the image based on pixels since each document will have separate spacing and line width
Thanks
Jk
Here is a solution that finds the brightest rows in the image (i.e., the rows without text) and then splits the image on those rows. So far I have just marked the sections, and am leaving the actual cropping up to you.
The algorithm is as follows:
Find the sum of the luminance (I am just using the red channel) of every pixel in each row
Find the rows with sums that are at least 0.999 (which is the threshold I am using) as bright as the brightest row
Mark those rows
Here is the code that will return a list of these rows:
def find_lightest_rows(img, threshold):
line_luminances = [0] * img.height
for y in range(img.height):
for x in range(img.width):
line_luminances[y] += img.getpixel((x, y))[0]
line_luminances = [x for x in enumerate(line_luminances)]
line_luminances.sort(key=lambda x: -x[1])
lightest_row_luminance = line_luminances[0][1]
lightest_rows = []
for row, lum in line_luminances:
if(lum > lightest_row_luminance * threshold):
lightest_rows.add(row)
return lightest_rows
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ... ]
After colouring these rows red, we have this image:
I have this data:
data2 is missing the third point. So I thought, I'd define two different x columns and assign data2 to x2.
Problem: the third point of data1 goes up to 3 in the compiled graphic. If I have different and more values, points start to go anywhere, but not where they belong.
That is the code I've used:
\addplot[only marks, mark = diamond, color = orange, mark size = 3pt]
table[x=x1, y=data1]{example.dat};
\addlegendentry{data1};
\addplot[only marks, mark = square, color = gray, mark size = 3pt]
table[x=x2, y=data2]{example.dat};
\addlegendentry{data2};
\addplot[only marks, mark = o, color = blue, mark size = 3pt]
table[x=x1, y=data3]{example.dat};
\addlegendentry{data3};
And this is the graph I get:
Thanks a lot!
Btw. in the real data one data set is missing a x/y value in the middle of the data. I hope that doesn't matter compared to my example.
pgfplots is interpreting 2 tabs as a single separator. Thus, it sees the data file as:
x1 x2 data1 data2 data3
0 0 1 2 3
1 1 1 2 3
2 1 3
Solution 1. You can replace empty cells with NaN. pgfplots will interpret this correctly:
x1 x2 data1 data2 data3
0 0 1 2 3
1 1 1 2 3
2 nan 1 nan 3
Solution 2. Use another type of separator (e.g., semicolons or commas):
\begin{filecontents*}{example.csv}
x1;x2;data1;data2;data3
0;0;1;2;3
1;1;1;2;3
2;;1;;3
\end{filecontents*}
\pgfplotstableread[col sep = semicolon]{example.csv}\mydata
\begin{document}
...
Here I've included the data file in the TeX file, but it should also work with a separate data file.
This is my code for slicing my 512*512 image into a cube of 64*64*64 dimension. but when i reshape it again into a 2D array why is it not giving me the original image.am i doing something incorrect please help.
clc;
im=ind2gray(y,ymap);
% im=imresize(im,0.125);
[rows ,columns, colbands] = size(im)
end
image3d=reshape(image3d,512,512);
figure,imshow(uint8(image3d));
Just a small hint.
P(:,:,1) = [0,0;0,0]
P(:,:,2) = [1,1;1,1]
P(:,:,3) = [2,2;2,2]
P(:,:,4) = [3,3;3,3]
B = reshape(P,4,4)
B =
0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3
So you might change the slicing or do the reshaping on your own.
If I have understood your question right, you can look into the code below to perform the same operation.
% Random image of the provided size 512X512
imageX = rand(512,512)
imagesc(imageX)
% Converting the image "imageX" into the cube of 64X64X64 dimension
sliceColWise = reshape(imageX,64,64,64)
size(sliceColWise)
% Reshaping the cube to obtain the image original that was "imageX",
% in order to observe that they are identical the difference is plotted
imageY = reshape(sliceColWise,512,512);
imagesc(imageX-imageY)
n.b: From MATLAB help you can see that the reshape works column wise
reshape(X,M,N) or reshape(X,[M,N]) returns the M-by-N matrix
whose elements are taken columnwise from X. An error results
if X does not have M*N elements.
I wrote a code that can get line projection (intensity profile) of an image, and I would like to convert/export this line projection (intensity profile) to excel table, and then order all the Y coordinate. For example, except the maximum and minimum values of all the Y coordinate, I would like to know largest 5 coordinate value and smallest coordinate value.
Is there any code can reach this function? Thanks,
image line_projection
Realimage imgexmp
imgexmp := GetFrontImage()
number samples = 256, xscale, yscale, xsize, ysize
GetSize( imgexmp, xsize, ysize )
line_projection := CreateFloatImage( "line projection", Xsize, 1 )
line_projection = 0
line_projection[icol,0] += imgexmp
line_projection /= samples
ShowImage( line_projection )
Finding a 'sorted' list of values
If you need to sort though large lists of values (i.e. large images) the following might not be very sufficient. However, if your aim is to get the "x highest" values with a relatively small number of X, then the following code is just fine:
number nFind = 10
image test := GetFrontImage().ImageClone()
Result( "\n\n" + nFind + " highest values:\n" )
number x,y,v
For( number i=0; i<nFind; i++ )
{
v = max(test,x,y)
Result( "\t" + v + " at " + x + "\n" )
test[x,y] = - Infinity()
}
Working with a copy and subsequently "removing" the maximum value by changing that pixel value. The max command is fast - even for large images -, but the for-loop iteration and setting of individual pixels is slow. Hence this script is too slow for a complete 'sorting' of the data if it is big, but it can quickly get you the n 'highest' values.
This is a non-coding answer:
If you havea LinePlot display in DigitalMicrograph, you can simply copy-paste that into Excel to get the numbers.
i.e. with the LinePlot image front most, preses CTRL + C to copy
(make sure there are no ROIs on it).
Switch to Excel and press CTRL + V. Done.
==>